Browse Source

初始化

master
徐振升 3 years ago
commit
d9be905995
  1. 17
      .browserslistrc
  2. 16
      .editorconfig
  3. 46
      .gitignore
  4. 15
      .vscode/launch.json
  5. 27
      README.md
  6. 112
      angular.json
  7. 37
      e2e/protractor.conf.js
  8. 23
      e2e/src/app.e2e-spec.ts
  9. 11
      e2e/src/app.po.ts
  10. 13
      e2e/tsconfig.json
  11. 44
      karma.conf.js
  12. 14727
      package-lock.json
  13. 60
      package.json
  14. 7180
      src/app/app.component.css
  15. 1
      src/app/app.component.html
  16. 10
      src/app/app.component.ts
  17. 59
      src/app/app.module.ts
  18. 390
      src/app/babylonjs/FireTruck.ts
  19. 162
      src/app/babylonjs/FireTruckInput.ts
  20. 4
      src/app/babylonjs/babylonjs.component.css
  21. 4
      src/app/babylonjs/babylonjs.component.html
  22. 195
      src/app/babylonjs/babylonjs.component.ts
  23. 1
      src/app/babylonjs/game.js
  24. 156
      src/app/blueprint/blueprint.component.css
  25. 225
      src/app/blueprint/blueprint.component.html
  26. 25
      src/app/blueprint/blueprint.component.spec.ts
  27. 550
      src/app/blueprint/blueprint.component.ts
  28. 0
      src/assets/.gitkeep
  29. BIN
      src/assets/GPC/CarColor.png
  30. BIN
      src/assets/GPC/FireCar.jpg
  31. BIN
      src/assets/GPC/GPC.bin
  32. 2750
      src/assets/GPC/GPC.gltf
  33. 0
      src/blueprint/blueprint.component.css
  34. 4
      src/blueprint/blueprint.component.html
  35. 25
      src/blueprint/blueprint.component.spec.ts
  36. 56
      src/blueprint/blueprint.component.ts
  37. 53
      src/blueprint/scripts/ParametricsInterface.js
  38. 139
      src/blueprint/scripts/blueprint.ts
  39. 83
      src/blueprint/scripts/core/EventSystem.ts
  40. 205
      src/blueprint/scripts/core/MessageSystem.ts
  41. 32
      src/blueprint/scripts/core/Singleton.ts
  42. 122
      src/blueprint/scripts/core/configuration.ts
  43. 32
      src/blueprint/scripts/core/constants.ts
  44. 146
      src/blueprint/scripts/core/dimensioning.ts
  45. 14
      src/blueprint/scripts/core/exposable.ts
  46. 58
      src/blueprint/scripts/core/log.ts
  47. 472
      src/blueprint/scripts/core/utils.js
  48. 28
      src/blueprint/scripts/core/version.ts
  49. 90
      src/blueprint/scripts/helpers/ConfigurationHelper.ts
  50. 16
      src/blueprint/scripts/helpers/DeviceInfo.ts
  51. 141
      src/blueprint/scripts/helpers/FloorplannerHelper.ts
  52. 221
      src/blueprint/scripts/helpers/RoomplannerHelper.ts
  53. 20
      src/blueprint/scripts/items/factory.js
  54. 32
      src/blueprint/scripts/items/floor_item.js
  55. 39
      src/blueprint/scripts/items/in_wall_floor_item.js
  56. 26
      src/blueprint/scripts/items/in_wall_item.js
  57. 400
      src/blueprint/scripts/items/item.js
  58. 11
      src/blueprint/scripts/items/on_floor_item.js
  59. 16
      src/blueprint/scripts/items/roof_item.js
  60. 43
      src/blueprint/scripts/items/wall_floor_item.js
  61. 68
      src/blueprint/scripts/items/wall_item.js
  62. 7
      src/blueprint/scripts/materials/FloorMaterial3D.js
  63. 241
      src/blueprint/scripts/materials/Material3D.js
  64. 7
      src/blueprint/scripts/materials/WallMaterial3D.js
  65. 172
      src/blueprint/scripts/model/boundary.ts
  66. 696
      src/blueprint/scripts/model/corner.ts
  67. 222
      src/blueprint/scripts/model/cornergroups.ts
  68. 1298
      src/blueprint/scripts/model/floorplan.ts
  69. 1028
      src/blueprint/scripts/model/half_edge.ts
  70. 146
      src/blueprint/scripts/model/model.ts
  71. 678
      src/blueprint/scripts/model/room.ts
  72. 743
      src/blueprint/scripts/model/wall.ts
  73. 0
      src/blueprint/scripts/page-not-found/page-not-found.component.css
  74. 123
      src/blueprint/scripts/page-not-found/page-not-found.component.html
  75. 25
      src/blueprint/scripts/page-not-found/page-not-found.component.spec.ts
  76. 15
      src/blueprint/scripts/page-not-found/page-not-found.component.ts
  77. 23
      src/blueprint/scripts/parametrics/ParametricFactory.js
  78. 16
      src/blueprint/scripts/parametrics/doors/DoorFactory.js
  79. 531
      src/blueprint/scripts/parametrics/doors/ParametricBaseDoor.js
  80. 147
      src/blueprint/scripts/parametrics/doors/ParametricDoorType2.js
  81. 54
      src/blueprint/scripts/parametrics/doors/ParametricDoorType3.js
  82. 55
      src/blueprint/scripts/parametrics/doors/ParametricDoorType4.js
  83. 53
      src/blueprint/scripts/parametrics/doors/ParametricDoorType5.js
  84. 52
      src/blueprint/scripts/parametrics/doors/ParametricDoorType6.js
  85. 149
      src/blueprint/scripts/parametrics/doors/doorhandles/DoorHandleGenerator.js
  86. 5
      src/blueprint/scripts/parametrics/doors/doorhandles/Handle_01.js
  87. 5
      src/blueprint/scripts/parametrics/doors/doorhandles/Handle_02.js
  88. 5
      src/blueprint/scripts/parametrics/doors/doorhandles/Handle_03.js
  89. 5
      src/blueprint/scripts/parametrics/doors/doorhandles/Handle_04.js
  90. 290
      src/blueprint/scripts/tempSrc/LShape.json
  91. 194
      src/blueprint/scripts/tempSrc/designWithBoundary.json
  92. 404
      src/blueprint/scripts/tempSrc/designWithoutBoundary.json
  93. 141
      src/blueprint/scripts/tempSrc/empty.json
  94. 176
      src/blueprint/scripts/tempSrc/empty_room.json
  95. 54
      src/blueprint/scripts/tempSrc/floor_textures.json
  96. 537
      src/blueprint/scripts/tempSrc/index.js
  97. 366
      src/blueprint/scripts/tempSrc/parametrics_items.json
  98. 81
      src/blueprint/scripts/tempSrc/wall_textures.json
  99. 203
      src/blueprint/scripts/viewer2d/BaseFloorplanViewElement2D.ts
  100. 95
      src/blueprint/scripts/viewer2d/BoundaryView2D.js
  101. Some files were not shown because too many files have changed in this diff Show More

17
.browserslistrc

@ -0,0 +1,17 @@
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# For the full list of supported browsers by the Angular framework, please see:
# https://angular.io/guide/browser-support
# You can see what browsers were selected by your queries by running:
# npx browserslist
last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major versions
last 2 iOS major versions
Firefox ESR
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.

16
.editorconfig

@ -0,0 +1,16 @@
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.ts]
quote_type = single
[*.md]
max_line_length = off
trim_trailing_whitespace = false

46
.gitignore vendored

@ -0,0 +1,46 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
/out-tsc
# Only exists if Bazel was run
/bazel-out
# dependencies
/node_modules
# profiling files
chrome-profiler-events*.json
speed-measure-plugin*.json
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings
# System Files
.DS_Store
Thumbs.db

15
.vscode/launch.json vendored

@ -0,0 +1,15 @@
{
// 使 IntelliSense
//
// 访: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "pwa-chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost:4200",
"webRoot": "${workspaceFolder}"
}
]
}

27
README.md

@ -0,0 +1,27 @@
# BabylonjsWebApp
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 11.2.10.
## Development server
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
## Code scaffolding
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
## Build
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
## Running unit tests
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Running end-to-end tests
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.

112
angular.json

@ -0,0 +1,112 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"BabylonjsWebApp": {
"projectType": "application",
"schematics": {},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/BabylonjsWebApp",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": true,
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", "src/styles.css"],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "BabylonjsWebApp:build"
},
"configurations": {
"production": {
"browserTarget": "BabylonjsWebApp:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "BabylonjsWebApp:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", "src/styles.css"],
"scripts": []
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"tsconfig.app.json",
"tsconfig.spec.json",
"e2e/tsconfig.json"
],
"exclude": ["**/node_modules/**"]
}
},
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "BabylonjsWebApp:serve"
},
"configurations": {
"production": {
"devServerTarget": "BabylonjsWebApp:serve:production"
}
}
}
}
}
},
"defaultProject": "BabylonjsWebApp"
}

37
e2e/protractor.conf.js

@ -0,0 +1,37 @@
// @ts-check
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter');
/**
* @type { import("protractor").Config }
*/
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
browserName: 'chrome'
},
directConnect: true,
SELENIUM_PROMISE_MANAGER: false,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.json')
});
jasmine.getEnv().addReporter(new SpecReporter({
spec: {
displayStacktrace: StacktraceOption.PRETTY
}
}));
}
};

23
e2e/src/app.e2e-spec.ts

@ -0,0 +1,23 @@
import { browser, logging } from 'protractor';
import { AppPage } from './app.po';
describe('workspace-project App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
it('should display welcome message', async () => {
await page.navigateTo();
expect(await page.getTitleText()).toEqual('BabylonjsWebApp app is running!');
});
afterEach(async () => {
// Assert that there are no errors emitted from the browser
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
expect(logs).not.toContain(jasmine.objectContaining({
level: logging.Level.SEVERE,
} as logging.Entry));
});
});

11
e2e/src/app.po.ts

@ -0,0 +1,11 @@
import { browser, by, element } from 'protractor';
export class AppPage {
async navigateTo(): Promise<unknown> {
return browser.get(browser.baseUrl);
}
async getTitleText(): Promise<string> {
return element(by.css('app-root .content span')).getText();
}
}

13
e2e/tsconfig.json

@ -0,0 +1,13 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/e2e",
"module": "commonjs",
"target": "es2018",
"types": [
"jasmine",
"node"
]
}
}

44
karma.conf.js

@ -0,0 +1,44 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
jasmine: {
// you can add configuration options for Jasmine here
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
// for example, you can disable the random execution with `random: false`
// or set a specific seed with `seed: 4321`
},
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
jasmineHtmlReporter: {
suppressAll: true // removes the duplicated traces
},
coverageReporter: {
dir: require('path').join(__dirname, './coverage/BabylonjsWebApp'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
]
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
});
};

14727
package-lock.json generated

File diff suppressed because it is too large Load Diff

60
package.json

@ -0,0 +1,60 @@
{
"name": "babylonjs-web-app",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "~11.2.11",
"@angular/cdk": "11.2.13",
"@angular/common": "~11.2.11",
"@angular/compiler": "~11.2.11",
"@angular/core": "~11.2.11",
"@angular/forms": "~11.2.11",
"@angular/material": "11.2.13",
"@angular/platform-browser": "~11.2.11",
"@angular/platform-browser-dynamic": "~11.2.11",
"@angular/router": "~11.2.11",
"@pixi/canvas-renderer": "^6.1.1",
"@types/bezier-js": "^4.1.0",
"@types/point-in-polygon": "^1.0.0",
"@types/quicksettings": "^3.0.0",
"babylonjs": "^5.0.0-alpha.40",
"babylonjs-loaders": "^5.0.0-alpha.40",
"babylonjs-materials": "^5.0.0-alpha.40",
"bezier-js": "^4.1.1",
"detect-touch-device": "^1.1.6",
"pixi-viewport": "^4.32.0",
"pixi.js": "^6.1.1",
"point-in-polygon": "^1.1.0",
"rxjs": "~6.6.0",
"three.js": "^0.77.1",
"tslib": "^2.0.0",
"zone.js": "~0.11.3"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.1102.10",
"@angular/cli": "~11.2.10",
"@angular/compiler-cli": "~11.2.11",
"@types/jasmine": "~3.6.0",
"@types/node": "^12.11.1",
"codelyzer": "^6.0.0",
"jasmine-core": "~3.6.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~6.1.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.0.3",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.5.0",
"protractor": "~7.0.0",
"ts-node": "~8.3.0",
"tslint": "~6.1.0",
"typescript": "~4.1.5"
}
}

7180
src/app/app.component.css

File diff suppressed because it is too large Load Diff

1
src/app/app.component.html

@ -0,0 +1 @@
<app-babylonjs></app-babylonjs>

10
src/app/app.component.ts

@ -0,0 +1,10 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
}

59
src/app/app.module.ts

@ -0,0 +1,59 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { BabylonjsComponent } from './babylonjs/babylonjs.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatButtonModule } from '@angular/material/button';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { MatDialogModule } from '@angular/material/dialog';
import { MatDividerModule } from '@angular/material/divider';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatListModule } from '@angular/material/list';
import { MatMenuModule } from '@angular/material/menu';
import { MatRadioModule } from '@angular/material/radio';
import { MatSelectModule } from '@angular/material/select';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatTooltipModule } from '@angular/material/tooltip';
import { BlueprintComponent } from './blueprint/blueprint.component';
@NgModule({
declarations: [
AppComponent,
BabylonjsComponent,
BlueprintComponent
],
imports: [
BrowserModule,
// RouterModule.forRoot([
// { path: 'babylonjs', component: BabylonjsComponent },
// { path: '', redirectTo: '/babylonjs', pathMatch: 'full' },
// { path: '**', component: PageNotFoundComponent }
// ]),
BrowserAnimationsModule,
MatButtonModule,
MatButtonToggleModule,
MatDialogModule,
MatDividerModule,
MatExpansionModule,
MatFormFieldModule,
MatIconModule,
MatInputModule,
MatListModule,
MatMenuModule,
MatRadioModule,
MatSelectModule,
MatSidenavModule,
MatToolbarModule,
MatTooltipModule,
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule { }

390
src/app/babylonjs/FireTruck.ts

@ -0,0 +1,390 @@
import { AnimationGroup, Axis, Mesh, Quaternion, Scene, SceneLoader, Space, TransformNode, Vector3, Node, Angle, DeepImmutable, Vector2, MeshBuilder, Color3 } from "babylonjs";
import { FireTruckInput } from "./FireTruckInput";
import "babylonjs-loaders";
export enum ArmActionState {
Bi,
Bi1,
Bi2,
Bi3,
Bi4,
Bi5,
Bi6,
Pentou,
}
export class FireTruck {
private targetPoint: Vector3 = null;
public input: FireTruckInput = null;
public speed: number = 1; // 速度
public tranlateSpeed: number = 5;//移动速度
public animations: AnimationGroup;
public root: Mesh = null; // Y轴旋转
public Bi: Mesh = null; // Y轴旋转
public Bi1: Mesh = null;// X轴旋转
public Bi2: Mesh = null;// 伸臂
public Bi3: Mesh = null;// 伸臂
public Bi4: Mesh = null;// 伸臂
public Bi5: Mesh = null;// 伸臂
public Bi6: Mesh = null;// X轴旋转
public Bi1Postion: Vector3 = null;
public Bi1MaxAngle: number = -84;
public Bi1MinAngle: number = -6;
// 最大臂长
public maxArmlength = 15;
// 最小臂长
public minArmlength = 0;
// Bi2
public Bi2Length = 0;
// Bi3
public Bi3Length = 0;
// Bi4
public Bi4Length = 0;
// Bi5
public Bi5Length = 0;
deltaTime: number = 1000;
private scene: Scene;
// 开始自动举臂
private beginArmAction = false;
// 自动举臂状态
private armActionState: ArmActionState = ArmActionState.Bi;
public center;
public box;
/**
*
*/
constructor(scene: Scene) {
this.scene = scene;
this.input = new FireTruckInput(scene);
SceneLoader.ImportMeshAsync("", "assets/GPC/", "GPC.gltf", scene).then(result => {
this.animations = scene.getAnimationGroupByName("All Animations");
this.animations.stop();
this.root = result.meshes[0] as Mesh;
this.Bi = scene.getMeshByName("Bi") as Mesh;
this.Bi1 = scene.getMeshByName("Bi1") as Mesh;
this.Bi2 = scene.getMeshByName("Bi2") as Mesh;
this.Bi2Length = this.Bi2.position.z;
this.Bi3 = scene.getMeshByName("Bi3") as Mesh;
this.Bi3Length = this.Bi3.position.z;
this.Bi4 = scene.getMeshByName("Bi4") as Mesh;
this.Bi4Length = this.Bi4.position.z;
this.Bi5 = scene.getMeshByName("Bi5") as Mesh;
this.Bi5Length = this.Bi5.position.z;
this.Bi6 = scene.getMeshByName("Bi6") as Mesh;
this.Bi1.rotationQuaternion = Quaternion.Identity();
this.Bi1Postion = this.Bi1.position.clone();
this.center = MeshBuilder.CreateBox("center", {}, scene);
this.box = MeshBuilder.CreateBox("box", { width: .5, height: .5, depth: 10 })
// this.box.parent = this.center;
// this.center.position.set(10, 0, 10);
// this.box.position.z = 5;
});
scene.registerBeforeRender(() => {
this.beforeRenderUpdate();
})
}
setTarget(pickedPoint: Vector3) {
this.targetPoint = pickedPoint;
this.armActionState = ArmActionState.Bi;
}
private beforeRenderUpdate(): void {
this.updateFromControls();
}
updateFromControls() {
this.deltaTime = this.scene.getEngine().getDeltaTime() / 1000.0;
if (this.input.U) {
this.RotateRoot(-this.deltaTime);
} else if (this.input.J) {
this.RotateRoot(this.deltaTime);
} else if (this.input.A) {
this.RotateBi(this.deltaTime);
} else if (this.input.D) {
this.RotateBi(-this.deltaTime);
} else if (this.input.W) {
this.RotateBi1(-this.deltaTime);
} else if (this.input.S) {
this.RotateBi1(this.deltaTime);
} else if (this.input.Q) {
this.TranlateBi2345(this.deltaTime * 5);
} else if (this.input.E) {
this.TranlateBi2345(-this.deltaTime * 5);
} else if (this.input.Z) {
this.RotateBi6(-this.deltaTime);
} else if (this.input.C) {
this.RotateBi6(this.deltaTime);
} else if (this.targetPoint != null) {
switch (this.armActionState) {
case ArmActionState.Bi:
this.AutoRotateBi();
break;
case ArmActionState.Bi1:
this.AutoRotateBi1();
break;
case ArmActionState.Bi2:
this.AutoTranlateBi(this.Bi2, ArmActionState.Bi3,)
break;
case ArmActionState.Bi3:
this.AutoTranlateBi(this.Bi3, ArmActionState.Bi4,)
break;
case ArmActionState.Bi4:
this.AutoTranlateBi(this.Bi4, ArmActionState.Bi5,)
break;
case ArmActionState.Bi5:
this.AutoTranlateBi(this.Bi5, ArmActionState.Bi1,)
break;
case ArmActionState.Bi6:
this.AutoRotateBi6();
break;
case ArmActionState.Pentou:
break;
}
}
}
public RotateRoot(angle: number) {
this.root.rotate(Axis.Y, angle, Space.LOCAL);
}
// 旋转B
public RotateBi(angle: number) {
this.Bi.rotate(Axis.Y, angle, Space.LOCAL);
}
// 自动旋转Bi
public AutoRotateBi() {
const v1 = this.targetPoint.subtract(this.Bi.absolutePosition);
const v2 = this.Bi.forward;
const dir = Vector3.Cross(v1, v2).y;
if (dir > 0.001) {
// 在顺时针方向
this.Bi.rotate(Axis.Y, this.deltaTime * this.speed, Space.LOCAL)
} else if (dir < -0.001) {
this.Bi.rotate(Axis.Y, this.deltaTime * -this.speed, Space.LOCAL)
} else {
console.log("==========");
this.armActionState = ArmActionState.Bi1;
}
// const q0 = Quaternion.FromLookDirectionRH(lookPosBox, Vector3.Up());
// if (!this.box.absoluteRotationQuaternion.equalsWithEpsilon(q0, 0.01)) {
// this.box.rotate(Axis.Y, 0.1, Space.LOCAL)
// }
// const lookPos = this.targetPoint.subtract(this.Bi.absolutePosition).normalize();
// lookPos.y = 0;
// const q1 = Quaternion.FromLookDirectionLH(lookPos, Vector3.Up());
// if (!this.Bi.absoluteRotationQuaternion.equalsWithEpsilon(q1, 0.01)) {
// this.Bi.rotate(Axis.Y, 0.005, Space.LOCAL)
// }
// const absoluteRotationQuaternion = Quaternion.FromLookDirectionLH(lookPos, Vector3.Up());
// const absoluteRotationQuaternionOffset = absoluteRotationQuaternion.subtract(this.root.absoluteRotationQuaternion);
// this.Bi.addRotation(0, absoluteRotationQuaternionOffset.toEulerAngles().y, 0);
// this.armActionState = ArmActionState.Bi2;
// this.Bi.rotationQuaternion = Quaternion.Slerp(this.Bi.rotationQuaternion, absoluteRotationQuaternionOffset.normalize(), this.deltaTime * 10);// TODO需要设置世界旋转
// if (this.Bi.rotationQuaternion.equalsWithEpsilon(rotation, 0.1)) {
// this.Bi.rotationQuaternion = rotation;
// // this.armActionState = ArmActionState.Bi2;
// console.log("旋转地盘结束");
// const line = MeshBuilder.CreateLines('line', { points: [this.targetPoint, this.Bi.absolutePosition] });
// line.color = Color3.Red();
// }
// const v1 = (new Vector3(this.targetPoint.x, this.Bi.position.y, this.targetPoint.z).subtract(this.Bi.position)).normalize();
// const v2 = this.root.forward;
// const targetDir = Vector3.Cross(v1, v2).y > 0 ? 1 : -1;
// const targetAngle = Math.acos(Vector3.Dot(v1, v2)) * 180 / Math.PI * targetDir;
// const currentAngle = this.Bi.rotationQuaternion.toEulerAngles().y * 180 / Math.PI;
// // console.log(this.Bi.rotationQuaternion.equalsWithEpsilon(new Quaternion(-rotation.x, -rotation.y, -rotation.z, rotation.w), 0.001));
// if (Math.abs(targetAngle - currentAngle) > 0.5) {
// const speedDir = (targetAngle - currentAngle) >= 0 ? 1 : -1;
// this.RotateBi(speedDir * 0.01);
// } else {
// this.armActionState = ArmActionState.Bi2;
// }
}
public RotateBi1(angle: number) {
this.Bi1.rotate(Axis.X, angle * 0.1, Space.LOCAL);
}
public AutoRotateBi1() {
const v1 = this.targetPoint.subtract(this.Bi.absolutePosition);
const v2 = this.Bi1.forward;
const dir = Vector3.Cross(v1.normalize(), v2.normalize()).x;
if (dir > 0.01) {
// 在顺时针方向
this.Bi1.rotate(Axis.X, this.deltaTime * this.speed, Space.LOCAL)
} else if (dir < -0.01) {
this.Bi1.rotate(Axis.X, this.deltaTime * -this.speed, Space.LOCAL)
} else {
console.log("已经转到指定方向");
this.armActionState = ArmActionState.Bi2;
}
// const d2E = Math.floor(Vector3.Distance(this.Bi6.absolutePosition, this.Bi.absolutePosition)) + 15;//臂长
// const d2T = Math.floor(Vector3.Distance(this.Bi.absolutePosition, this.targetPoint));//臂底端到目标的距离
// const distance = Math.round(Vector3.Distance(this.Bi6.absolutePosition, this.targetPoint)); //Bi6到目标距离
// const v1 = (new Vector3(this.targetPoint.x, this.targetPoint.y, this.targetPoint.z).subtract(this.Bi1.position)).normalize();
// const v2 = this.Bi.forward.normalize();
// const targetDir = Vector3.Cross(v1, v2).x > 0 ? -1 : 1;
// const lookPos = this.targetPoint.subtract(this.Bi1.position).normalize();
// const rotation = Quaternion.FromLookDirectionRH(lookPos, this.Bi1.up);
// this.Bi1.rotationQuaternion = Quaternion.Slerp(this.Bi1.rotationQuaternion, new Quaternion(rotation.x, rotation.y, rotation.z, rotation.w), this.deltaTime * 10);
// const targetAngle = Math.acos(Vector3.Dot(v1, v2)) * 180 / Math.PI * targetDir;
// const currentAngle = this.Bi1.rotationQuaternion.toEulerAngles().x * 180 / Math.PI;
// console.log(currentAngle,);
// console.log(targetAngle, "=================");
// if (Math.abs(targetAngle - currentAngle) > 0.5) {
// const speedDir = (targetAngle - currentAngle) >= 0 ? 1 : -1;
// this.RotateBi1(speedDir * 0.01);
// } else {
// this.armActionState = ArmActionState.Bi6;
// }
// console.log(distance, '')
// if (d2E < d2T) {
// // todo 直接指向目标点
// this.armActionState = ArmActionState.Bi6;
// } else {
// // 根据距离上调或下调
// if (distance < 15) {
// this.RotateBi1(-this.deltaTime);
// } else if (distance > 15) {
// this.RotateBi1(this.deltaTime);
// } else {
// this.armActionState = ArmActionState.Bi6;
// }
// }
}
public RotateBi6(angle: number) {
this.Bi6.rotate(Axis.X, angle, Space.LOCAL);
}
public AutoRotateBi6() {
// const v1 = (new Vector3(this.targetPoint.x, this.targetPoint.y, this.targetPoint.z).subtract(this.Bi6.position)).normalize();
// const v2 = this.Bi.forward.normalize();
// const targetDir = Vector3.Cross(v1, v2).x > 0 ? -1 : 1;
// const targetAngle = Math.acos(Vector3.Dot(v1, v2)) * 180 / Math.PI * targetDir;
// const currentAngle = this.Bi6.rotationQuaternion.toEulerAngles().x * 180 / Math.PI;
// const test = Vector3.GetAngleBetweenVectors(v1, this.Bi1.forward.normalize(), this.Bi1.up.normalize()) * 180 / Math.PI;
// const isUp = Math.abs(this.Bi6.rotationQuaternion.toEulerAngles().y) < 0.1 && Math.abs(this.Bi6.rotationQuaternion.toEulerAngles().z) < 0.1;
// const isZero = test - currentAngle > 0;
// if (test - currentAngle < 0.5 && isZero && isUp) {
// // this.armActionState = ArmActionState.Pentou;
// } else {
// if (isUp) {
// if (isZero) {
// this.RotateBi6(0.01);
// console.log("0");
// } else {
// this.RotateBi6(-0.01);
// console.log("1");
// }
// } else {
// this.RotateBi6(-0.01);
// console.log("2");
// }
// }
// console.log(test, 'Angle', isUp);
// console.log(currentAngle, this.Bi6.rotationQuaternion.toEulerAngles().y, this.Bi6.rotationQuaternion.toEulerAngles().z);
}
// 移动举臂
public TranlateBi2345(angle: number) {
switch (this.armActionState) {
case ArmActionState.Bi3:
this.TranlateBi(this.Bi3, ArmActionState.Bi4, angle)
break;
case ArmActionState.Bi4:
this.TranlateBi(this.Bi4, ArmActionState.Bi5, angle)
break;
case ArmActionState.Bi5:
this.TranlateBi(this.Bi5, ArmActionState.Bi1, angle)
break;
default:
this.TranlateBi(this.Bi2, ArmActionState.Bi3, angle)
break;
}
}
public TranlateBi(tranlateMesh: Mesh, nextState: ArmActionState, angle: number) {
tranlateMesh.translate(Axis.Z, angle, Space.LOCAL);
if (tranlateMesh.position.z > this.maxArmlength) {
tranlateMesh.position.z = this.maxArmlength;
this.armActionState = nextState;
} else if (tranlateMesh.position.z < this.minArmlength) {
tranlateMesh.position.z = this.minArmlength;
this.armActionState = nextState;
}
}
// 移动举臂
public AutoTranlateBi(tranlateMesh: Mesh, nextState: ArmActionState) {
//#region 自动伸臂
const d2E = Math.floor(Vector3.Distance(this.Bi6.absolutePosition, this.Bi.absolutePosition)) + 15;//臂长
const d2T = Math.floor(Vector3.Distance(this.Bi.absolutePosition, this.targetPoint));//臂底端到目标的距离
// console.log("当前臂长:", d2E, d2T);
// 臂长小于目标距离,伸臂
if (d2E < d2T) {
tranlateMesh.translate(Axis.Z, this.deltaTime * this.tranlateSpeed, Space.LOCAL);
if (tranlateMesh.position.z > this.maxArmlength) {
tranlateMesh.position.z = this.maxArmlength;
this.armActionState = nextState;
} else if (tranlateMesh.position.z < this.minArmlength) {
tranlateMesh.position.z = this.minArmlength;
this.armActionState = nextState;
}
}
else if (d2E > d2T) {
tranlateMesh.translate(Axis.Z, -this.deltaTime * this.tranlateSpeed, Space.LOCAL);
if (tranlateMesh.position.z > this.maxArmlength) {
tranlateMesh.position.z = this.maxArmlength;
this.armActionState = nextState;
} else if (tranlateMesh.position.z < this.minArmlength) {
tranlateMesh.position.z = this.minArmlength;
this.armActionState = nextState;
}
}
else {
this.armActionState = nextState;
}
//#endregion
}
}

162
src/app/babylonjs/FireTruckInput.ts

@ -0,0 +1,162 @@
import { Scene, ActionManager, ExecuteCodeAction, Observer, Scalar } from 'babylonjs';
export class FireTruckInput {
public inputMap: Map<string, boolean> = new Map<string, boolean>();
private scene: Scene;
//ArrowLeft,ArrowRight
private arrowLeft: boolean = false;
public get ArrowLeft(): boolean {
return this.arrowLeft;
}
private arrowRight: boolean = false;
public get ArrowRight(): boolean {
return this.arrowRight;
}
//w,s,a,d,q,e,z,c,u,j
private w: boolean = false;
public get W(): boolean {
return this.w;
}
private s: boolean = false;
public get S(): boolean {
return this.s;
}
private a: boolean = false;
public get A(): boolean {
return this.a;
}
private d: boolean = false;
public get D(): boolean {
return this.d;
}
private q: boolean = false;
public get Q(): boolean {
return this.q;
}
private e: boolean = false;
public get E(): boolean {
return this.e;
}
private z: boolean = false;
public get Z(): boolean {
return this.z;
}
private c: boolean = false;
public get C(): boolean {
return this.c;
}
private u: boolean = false;
public get U(): boolean {
return this.u;
}
private j: boolean = false;
public get J(): boolean {
return this.j;
}
constructor(scene: Scene) {
this.scene = scene;
// this._ui = ui;
//scene action manager to detect inputs
this.scene.actionManager = new ActionManager(this.scene);
this.scene.actionManager.registerAction(new ExecuteCodeAction(ActionManager.OnKeyDownTrigger, (evt) => {
this.inputMap.set(evt.sourceEvent.key, evt.sourceEvent.type == "keydown");
}));
this.scene.actionManager.registerAction(new ExecuteCodeAction(ActionManager.OnKeyUpTrigger, (evt) => {
this.inputMap.set(evt.sourceEvent.key, evt.sourceEvent.type == "keydown");
}));
// 添加监听
scene.onBeforeRenderObservable.add(() => {
this.updateFromKeyboard();
});
}
// 是否有控制键按下
public isKeyDown(): boolean {
return this.arrowLeft || this.arrowRight
|| this.w || this.s || this.a || this.d || this.q || this.e || this.z || this.c || this.u || this.j;
}
// 键盘控制
private updateFromKeyboard(): void {
//ArrowLeft
if (this.inputMap.get("ArrowLeft")) {
this.arrowLeft = true;
} else {
this.arrowLeft = false;
}
//ArrowRight
if (this.inputMap.get("ArrowRight")) {
this.arrowRight = true;
} else {
this.arrowRight = false;
}
//w
if (this.inputMap.get("w")) {
this.w = true;
} else {
this.w = false;
}
//s
if (this.inputMap.get("s")) {
this.s = true;
} else {
this.s = false;
}
//a
if (this.inputMap.get("a")) {
this.a = true;
} else {
this.a = false;
}
//d
if (this.inputMap.get("d")) {
this.d = true;
} else {
this.d = false;
}
//q
if (this.inputMap.get("q")) {
this.q = true;
} else {
this.q = false;
}
//e
if (this.inputMap.get("e")) {
this.e = true;
} else {
this.e = false;
}
//z
if (this.inputMap.get("z")) {
this.z = true;
} else {
this.z = false;
}
//c
if (this.inputMap.get("c")) {
this.c = true;
} else {
this.c = false;
}
//u
if (this.inputMap.get("u")) {
this.u = true;
} else {
this.u = false;
}
//j
if (this.inputMap.get("j")) {
this.j = true;
} else {
this.j = false;
}
}
}

4
src/app/babylonjs/babylonjs.component.css

@ -0,0 +1,4 @@
canvas {
width: calc(100% - 4px);
height: calc(100% - 68px);
}

4
src/app/babylonjs/babylonjs.component.html

@ -0,0 +1,4 @@
<canvas #renderCanvas id="renderCanvas1">
抱歉,您的浏览器不支持canvas元素
(这些内容将会在不支持元素的浏览器或是禁用了JavaScript的浏览器内渲染并展现)
</canvas>

195
src/app/babylonjs/babylonjs.component.ts

@ -0,0 +1,195 @@
import { AfterViewInit, Component, ElementRef, OnInit, Renderer2, ViewChild } from '@angular/core';
import { AbstractMesh, Angle, AnimationGroup, ArcRotateCamera, Axis, Color3, DeviceSourceManager, DirectionalLight, Engine, FreeCamera, Geometry, HemisphericLight, IParticleSystem, Light, Mesh, MeshBuilder, PickingInfo, PointerEventTypes, Scene, SceneLoader, Skeleton, Space, StandardMaterial, TransformNode, UniversalCamera, Vector3 } from 'babylonjs';
import { GridMaterial } from 'babylonjs-materials';
import { FireTruckInput } from './FireTruckInput';
import { FireTruck } from './FireTruck';
@Component({
selector: 'app-babylonjs',
templateUrl: './babylonjs.component.html',
styleUrls: ['./babylonjs.component.css']
})
export class BabylonjsComponent implements OnInit {
@ViewChild('renderCanvas', { read: ElementRef, static: true })
public canvasRef: ElementRef;
// public scene: Scene = null;
constructor(private renderer: Renderer2) {
console.log(this.canvasRef);
}
ngOnInit(): void {
this.AnimationTest();
}
public AnimationTest() {
// 获取Canvas
const canvas = this.canvasRef.nativeElement as HTMLCanvasElement;
// 创建引擎对象
const engine = new Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true });
// 创建一个场景
const scene = new Scene(engine);
const camera = new ArcRotateCamera('camera1', Math.PI / 3, 5 * Math.PI / 12, 3, new Vector3(0, 0, 0), scene);
camera.inputs.attached
// Target the camera to scene origin
camera.setTarget(new Vector3(1.219, 5.115, 0.565));
// Attach the camera to the canvas
camera.attachControl(canvas, false);
camera.radius = 60;
camera.alpha = 3.4;
camera.beta = 1.3;
// Create a basic light, aiming 0, 1, 0 - meaning, to the sky
const light = new HemisphericLight('light1', new Vector3(0, 1, 0), scene);
const ground = MeshBuilder.CreateGround('地面', { width: 200, height: 200 }, scene);
const sphere = MeshBuilder.CreateSphere("sphere", {});
var materialSphere = new StandardMaterial("texture1", scene);
materialSphere.diffuseColor = new Color3(1, 0, 0);
sphere.material = materialSphere;
const box1 = MeshBuilder.CreateBox("box1", { width: 200, height: 100 });
const box2 = MeshBuilder.CreateBox("box2", { width: 1, height: 100, depth: 200 });
const box3 = MeshBuilder.CreateBox("box3", { width: 200, height: 100 });
const box4 = MeshBuilder.CreateBox("box4", { width: 1, height: 100, depth: 200 });
box1.position.set(0, 50, 100);
box2.position.set(100, 50, 0);
box3.position.set(0, 50, -100);
box4.position.set(-100, 50, 0);
const fireTruck = new FireTruck(scene);
// 检测鼠标点击事件
scene.onPointerDown = (evt: PointerEvent, pickInfo: PickingInfo, type: PointerEventTypes) => {
if (pickInfo.hit) {
sphere.position = pickInfo.pickedPoint;
fireTruck.setTarget(sphere.absolutePosition);
}
}
window.addEventListener("keydown", (ev) => {
// Shift+Ctrl+Alt+I
if (ev.shiftKey && ev.ctrlKey && ev.altKey && ev.keyCode === 73) {
if (scene.debugLayer.isVisible()) {
scene.debugLayer.hide();
} else {
scene.debugLayer.show();
}
}
});
// run the render loop
engine.runRenderLoop(() => {
scene.render();
});
}
public createScene(): Scene {
// 获取Canvas
const canvas = this.canvasRef.nativeElement as HTMLCanvasElement;
// 创建引擎对象
const engine = new Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true });
// 创建一个场景
const scene = new Scene(engine);
// 创建相机
const camera = new ArcRotateCamera('camera1', Math.PI / 3, 5 * Math.PI / 12, 3, new Vector3(0, 0, 0), scene);
// Target the camera to scene origin
// camera.setTarget(Vector3.Zero());
// Attach the camera to the canvas
camera.attachControl(canvas, false);
// Create a basic light, aiming 0, 1, 0 - meaning, to the sky
const light = new HemisphericLight('light1', new Vector3(0, 1, 0), scene);
// run the render loop
engine.runRenderLoop(() => {
scene.render();
camera.alpha += 0.003;
});
// the canvas/window resize event handler
window.addEventListener('resize', () => {
engine.resize();
});
return scene;
}
public createGroundX(scene: Scene): void {
const groundMaterial = new GridMaterial('groundMaterial', scene);
groundMaterial.majorUnitFrequency = 10;
// groundMaterial.minorUnitVisibility = 0.45;
groundMaterial.gridRatio = 1;
groundMaterial.backFaceCulling = false;
groundMaterial.mainColor = new Color3(1, 1, 1);
groundMaterial.lineColor = new Color3(1.0, 1.0, 1.0);
groundMaterial.opacity = 0.98;
const ground = Mesh.CreateGround('ground', 10000, 10000, 0, scene, false);
ground.material = groundMaterial;
ground.position.x = 5000;
ground.position.z = 5000;
}
public createGroundY(scene: Scene): void {
const groundMaterial = new GridMaterial('groundMaterial', scene);
groundMaterial.majorUnitFrequency = 10;
// groundMaterial.minorUnitVisibility = 0.45;
groundMaterial.gridRatio = 1;
groundMaterial.backFaceCulling = false;
groundMaterial.mainColor = new Color3(1, 1, 1);
groundMaterial.lineColor = new Color3(1.0, 1.0, 1.0);
groundMaterial.opacity = 0.98;
const ground = Mesh.CreateGround('ground', 10000, 10000, 0, scene, false);
ground.material = groundMaterial;
ground.position.x = 5000;
ground.position.y = 5000;
ground.rotation = new Vector3(Angle.FromDegrees(90).radians(), 0, 0);
}
public createGroundZ(scene: Scene): void {
const groundMaterial = new GridMaterial('groundMaterial', scene);
groundMaterial.majorUnitFrequency = 10;
// groundMaterial.minorUnitVisibility = 0.45;
groundMaterial.gridRatio = 1;
groundMaterial.backFaceCulling = false;
groundMaterial.mainColor = new Color3(1, 1, 1);
groundMaterial.lineColor = new Color3(1.0, 1.0, 1.0);
groundMaterial.opacity = 0.98;
const ground = Mesh.CreateGround('ground', 10000, 10000, 0, scene, false);
ground.material = groundMaterial;
ground.position.y = 5000;
ground.position.z = 5000;
ground.rotation = new Vector3(0, 0, Angle.FromDegrees(90).radians());
}
// 创建本地坐标系
public createLocalAxes(scene: Scene): Mesh {
const size = 20;
let pilot_local_axisX = Mesh.CreateLines('pilot_local_axisX', [
Vector3.Zero(), new Vector3(size, 0, 0), new Vector3(size * 0.95, 0.05 * size, 0),
new Vector3(size, 0, 0), new Vector3(size * 0.95, -0.05 * size, 0)
], scene);
pilot_local_axisX.color = new Color3(1, 0, 0);
let pilot_local_axisY = Mesh.CreateLines('pilot_local_axisY', [
Vector3.Zero(), new Vector3(0, size, 0), new Vector3(-0.05 * size, size * 0.95, 0),
new Vector3(0, size, 0), new Vector3(0.05 * size, size * 0.95, 0)
], scene);
pilot_local_axisY.color = new Color3(0, 1, 0);
let pilot_local_axisZ = Mesh.CreateLines('pilot_local_axisZ', [
Vector3.Zero(), new Vector3(0, 0, size), new Vector3(0, -0.05 * size, size * 0.95),
new Vector3(0, 0, size), new Vector3(0, 0.05 * size, size * 0.95)
], scene);
pilot_local_axisZ.color = new Color3(0, 0, 1);
let local_origin = MeshBuilder.CreateBox('local_origin', { size: 1 }, scene);
local_origin.isVisible = false;
pilot_local_axisX.parent = local_origin;
pilot_local_axisY.parent = local_origin;
pilot_local_axisZ.parent = local_origin;
return local_origin;
}
}

1
src/app/babylonjs/game.js

File diff suppressed because one or more lines are too long

156
src/app/blueprint/blueprint.component.css

@ -0,0 +1,156 @@
/*
* General Formatting
*/
html {
overflow: hidden;
height: 100%;
}
body {
margin: 0;
padding: 0;
overflow: hidden;
height: 100%;
}
div {
margin: 0;
padding: 0;
}
/*
* Sidebar
*/
.main-row {
padding: 0;
}
.sidebar {
padding: 20px;
overflow-x: hidden;
overflow-y: auto;
border-right: 1px solid #eee;
}
.nav-sidebar {
margin-right: -21px; /* 20px padding + 1px border */
margin-bottom: 20px;
margin-left: -20px;
}
.nav-sidebar > li > a {
padding-right: 20px;
padding-left: 20px;
}
.nav-sidebar > .active > a,
.nav-sidebar > .active > a:hover,
.nav-sidebar > .active > a:focus {
color: #fff;
background-color: #428bca;
}
/*
* Main content
*/
.main {
padding: 0;
}
/*
* "Loading" modal
*/
#loading-modal {
position: absolute;
z-index: 10;
left: 0;
top: 0;
width: 100%;
height: 100%;
padding: 20px;
background-color: rgba(50, 50, 50, 0.9);
}
#loading-modal h1 {
text-align: center;
margin-top: 30%;
color: #fff;
}
/*
* Design
*/
#viewer {
display: none;
}
#floorplanner {
display: none;
}
#add-items {
display: none;
padding: 20px;
overflow-y: auto;
}
#main-controls {
position: absolute;
top: 20px;
left: 20px;
padding: 0;
}
#camera-controls {
position: absolute;
bottom: 20px;
right: 0;
padding: 0 20px;
text-align: right;
}
#floorplanner-controls {
position: absolute;
left: 0;
top: 0;
margin: 20px 0;
padding: 0 20px;
width: 100%;
}
#draw-walls-hint {
position: absolute;
left: 20px;
bottom: 20px;
background-color: rgba(0, 0, 0, 0.5);
color: #ffffff;
padding: 5px 10px;
z-index: 10;
display: none;
}
.add-item {
cursor: pointer;
}
.btn-file {
display: inline-block;
cursor: pointer;
position: relative;
overflow: hidden;
}
.btn-file input[type="file"] {
position: absolute;
top: 0;
right: 0;
min-width: 100%;
min-height: 100%;
filter: alpha(opacity=0);
opacity: 0;
cursor: inherit;
display: block;
}

225
src/app/blueprint/blueprint.component.html

@ -0,0 +1,225 @@
<!DOCTYPE html>
<html>
<head>
<title>Blueprint 3D - Example</title>
</head>
<body>
<div class="container-fluid">
<div class="row main-row">
<!-- Left Column -->
<div class="col-xs-3 sidebar">
<!-- Main Navigation -->
<ul class="nav nav-sidebar">
<li id="floorplan_tab"><a href="#">
Edit Floorplan
<span class="glyphicon glyphicon-chevron-right pull-right"></span>
</a></li>
<li id="design_tab"><a href="#">
Design
<span class="glyphicon glyphicon-chevron-right pull-right"></span>
</a></li>
<li id="items_tab"><a href="#">
Add Items
<span class="glyphicon glyphicon-chevron-right pull-right"></span>
</a></li>
</ul>
<hr />
<!-- Context Menu -->
<div id="context-menu">
<div style="margin: 0 20px">
<span id="context-menu-name" class="lead"></span>
<br /><br />
<button class="btn btn-block btn-danger" id="context-menu-delete">
<span class="glyphicon glyphicon-trash"></span>
Delete Item
</button>
<br />
<div class="panel panel-default">
<div class="panel-heading">Adjust Size</div>
<div class="panel-body" style="color: #333333">
<div class="form form-horizontal" class="lead">
<div class="form-group">
<label class="col-sm-5 control-label">
Width
</label>
<div class="col-sm-6">
<input type="number" class="form-control" id="item-width">
</div>
</div>
<div class="form-group">
<label class="col-sm-5 control-label">
Depth
</label>
<div class="col-sm-6">
<input type="number" class="form-control" id="item-depth">
</div>
</div>
<div class="form-group">
<label class="col-sm-5 control-label">
Height
</label>
<div class="col-sm-6">
<input type="number" class="form-control" id="item-height">
</div>
</div>
</div>
<small><span class="text-muted">Measurements in inches.</span></small>
</div>
</div>
<label><input type="checkbox" id="fixed" /> Lock in place</label>
<br /><br />
</div>
</div>
<!-- Floor textures -->
<div id="floorTexturesDiv" style="display:none; padding: 0 20px">
<div class="panel panel-default">
<div class="panel-heading">Adjust Floor</div>
<div class="panel-body" style="color: #333333">
<div class="col-sm-6" style="padding: 3px">
<a href="#" class="thumbnail texture-select-thumbnail"
texture-url="rooms/textures/light_fine_wood.jpg" texture-stretch="false"
texture-scale="300">
<img alt="Thumbnail light fine wood"
src="rooms/thumbnails/thumbnail_light_fine_wood.jpg" />
</a>
</div>
</div>
</div>
</div>
<!-- Wall Textures -->
<div id="wallTextures" style="display:none; padding: 0 20px">
<div class="panel panel-default">
<div class="panel-heading">Adjust Wall</div>
<div class="panel-body" style="color: #333333">
<div class="col-sm-6" style="padding: 3px">
<a href="#" class="thumbnail texture-select-thumbnail"
texture-url="rooms/textures/marbletiles.jpg" texture-stretch="false"
texture-scale="300">
<img alt="Thumbnail marbletiles" src="rooms/thumbnails/thumbnail_marbletiles.jpg" />
</a>
</div>
<div class="col-sm-6" style="padding: 3px">
<a href="#" class="thumbnail texture-select-thumbnail"
texture-url="rooms/textures/wallmap_yellow.png" texture-stretch="true"
texture-scale="">
<img alt="Thumbnail wallmap yellow"
src="rooms/thumbnails/thumbnail_wallmap_yellow.png" />
</a>
</div>
<div class="col-sm-6" style="padding: 3px">
<a href="#" class="thumbnail texture-select-thumbnail"
texture-url="rooms/textures/light_brick.jpg" texture-stretch="false"
texture-scale="100">
<img alt="Thumbnail light brick" src="rooms/thumbnails/thumbnail_light_brick.jpg" />
</a>
</div>
</div>
</div>
</div>
</div>
<!-- Right Column -->
<div class="col-xs-9 main">
<!-- 3D Viewer -->
<div id="viewer">
<div id="main-controls">
<a href="#" class="btn btn-default btn-sm" id="new">
New Plan
</a>
<a href="#" class="btn btn-default btn-sm" id="saveFile">
Save Plan
</a>
<a class="btn btn-sm btn-default btn-file">
<input type="file" class="hidden-input" id="loadFile">
Load Plan
</a>
</div>
<div id="camera-controls">
<a href="#" class="btn btn-default bottom" id="zoom-out">
<span class="glyphicon glyphicon-zoom-out"></span>
</a>
<a href="#" class="btn btn-default bottom" id="reset-view">
<span class="glyphicon glyphicon glyphicon-home"></span>
</a>
<a href="#" class="btn btn-default bottom" id="zoom-in">
<span class="glyphicon glyphicon-zoom-in"></span>
</a>
<span>&nbsp;</span>
<a class="btn btn-default bottom" href="#" id="move-left">
<span class="glyphicon glyphicon-arrow-left"></span>
</a>
<span class="btn-group-vertical">
<a class="btn btn-default" href="#" id="move-up">
<span class="glyphicon glyphicon-arrow-up"></span>
</a>
<a class="btn btn-default" href="#" id="move-down">
<span class="glyphicon glyphicon-arrow-down"></span>
</a>
</span>
<a class="btn btn-default bottom" href="#" id="move-right">
<span class="glyphicon glyphicon-arrow-right"></span>
</a>
</div>
<div id="loading-modal">
<h1>Loading...</h1>
</div>
</div>
<!-- 2D Floorplanner -->
<div id="floorplanner">
<canvas id="floorplanner-canvas"></canvas>
<div id="floorplanner-controls">
<button id="move" class="btn btn-sm btn-default">
<span class="glyphicon glyphicon-move"></span>
Move Walls
</button>
<button id="draw" class="btn btn-sm btn-default">
<span class="glyphicon glyphicon-pencil"></span>
Draw Walls
</button>
<button id="delete" class="btn btn-sm btn-default">
<span class="glyphicon glyphicon-remove"></span>
Delete Walls
</button>
<span class="pull-right">
<button class="btn btn-primary btn-sm" id="update-floorplan">Done &raquo;</button>
</span>
</div>
<div id="draw-walls-hint">
Press the "Esc" key to stop drawing walls
</div>
</div>
<!-- Add Items -->
<div id="add-items">
<div class="row" id="items-wrapper">
<!-- Items added here by items.js -->
</div>
</div>
</div>
<!-- End Right Column -->
</div>
</div>
</body>
</html>

25
src/app/blueprint/blueprint.component.spec.ts

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { BlueprintComponent } from './blueprint.component';
describe('BlueprintComponent', () => {
let component: BlueprintComponent;
let fixture: ComponentFixture<BlueprintComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ BlueprintComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(BlueprintComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

550
src/app/blueprint/blueprint.component.ts

@ -0,0 +1,550 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-blueprint',
templateUrl: './blueprint.component.html',
styleUrls: ['./blueprint.component.css']
})
export class BlueprintComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
// /*
// * Camera Buttons
// */
// CameraButtons(blueprint3d) {
// var orbitControls = blueprint3d.three.controls;
// var three = blueprint3d.three;
// var panSpeed = 30;
// var directions = {
// UP: 1,
// DOWN: 2,
// LEFT: 3,
// RIGHT: 4
// }
// function init() {
// // Camera controls
// $("#zoom-in").click(zoomIn);
// $("#zoom-out").click(zoomOut);
// $("#zoom-in").dblclick(preventDefault);
// $("#zoom-out").dblclick(preventDefault);
// $("#reset-view").click(three.centerCamera)
// $("#move-left").click(function () {
// pan(directions.LEFT)
// })
// $("#move-right").click(function () {
// pan(directions.RIGHT)
// })
// $("#move-up").click(function () {
// pan(directions.UP)
// })
// $("#move-down").click(function () {
// pan(directions.DOWN)
// })
// $("#move-left").dblclick(preventDefault);
// $("#move-right").dblclick(preventDefault);
// $("#move-up").dblclick(preventDefault);
// $("#move-down").dblclick(preventDefault);
// }
// function preventDefault(e) {
// e.preventDefault();
// e.stopPropagation();
// }
// function pan(direction) {
// switch (direction) {
// case directions.UP:
// orbitControls.panXY(0, panSpeed);
// break;
// case directions.DOWN:
// orbitControls.panXY(0, -panSpeed);
// break;
// case directions.LEFT:
// orbitControls.panXY(panSpeed, 0);
// break;
// case directions.RIGHT:
// orbitControls.panXY(-panSpeed, 0);
// break;
// }
// }
// zoomIn(e) {
// e.preventDefault();
// orbitControls.dollyIn(1.1);
// orbitControls.update();
// }
// zoomOut(e) {
// e.preventDefault;
// orbitControls.dollyOut(1.1);
// orbitControls.update();
// }
// init();
// }
// /*
// * Context menu for selected item
// */
// ContextMenu(blueprint3d) {
// var scope = this;
// var selectedItem;
// var three = blueprint3d.three;
// function init() {
// $("#context-menu-delete").click(function (event) {
// selectedItem.remove();
// });
// three.itemSelectedCallbacks.add(itemSelected);
// three.itemUnselectedCallbacks.add(itemUnselected);
// initResize();
// $("#fixed").click(function () {
// var checked = $(this).prop('checked');
// selectedItem.setFixed(checked);
// });
// }
// function cmToIn(cm) {
// return cm / 2.54;
// }
// function inToCm(inches) {
// return inches * 2.54;
// }
// function itemSelected(item) {
// selectedItem = item;
// $("#context-menu-name").text(item.metadata.itemName);
// $("#item-width").val(cmToIn(selectedItem.getWidth()).toFixed(0));
// $("#item-height").val(cmToIn(selectedItem.getHeight()).toFixed(0));
// $("#item-depth").val(cmToIn(selectedItem.getDepth()).toFixed(0));
// $("#context-menu").show();
// $("#fixed").prop('checked', item.fixed);
// }
// function resize() {
// selectedItem.resize(
// inToCm($("#item-height").val()),
// inToCm($("#item-width").val()),
// inToCm($("#item-depth").val())
// );
// }
// function initResize() {
// $("#item-height").change(resize);
// $("#item-width").change(resize);
// $("#item-depth").change(resize);
// }
// function itemUnselected() {
// selectedItem = null;
// $("#context-menu").hide();
// }
// init();
// }
// /*
// * Loading modal for items
// */
// ModalEffects(blueprint3d) {
// var scope = this;
// var blueprint3d = blueprint3d;
// var itemsLoading = 0;
// this.setActiveItem = function (active) {
// itemSelected = active;
// update();
// }
// function update() {
// if (itemsLoading > 0) {
// $("#loading-modal").show();
// } else {
// $("#loading-modal").hide();
// }
// }
// function init() {
// blueprint3d.model.scene.itemLoadingCallbacks.add(function () {
// itemsLoading += 1;
// update();
// });
// blueprint3d.model.scene.itemLoadedCallbacks.add(function () {
// itemsLoading -= 1;
// update();
// });
// update();
// }
// init();
// }
// /*
// * Side menu
// */
// SideMenu(blueprint3d, floorplanControls, modalEffects) {
// var blueprint3d = blueprint3d;
// var floorplanControls = floorplanControls;
// var modalEffects = modalEffects;
// var ACTIVE_CLASS = "active";
// var tabs = {
// "FLOORPLAN": $("#floorplan_tab"),
// "SHOP": $("#items_tab"),
// "DESIGN": $("#design_tab")
// }
// var scope = this;
// this.stateChangeCallbacks = $.Callbacks();
// this.states = {
// "DEFAULT": {
// "div": $("#viewer"),
// "tab": tabs.DESIGN
// },
// "FLOORPLAN": {
// "div": $("#floorplanner"),
// "tab": tabs.FLOORPLAN
// },
// "SHOP": {
// "div": $("#add-items"),
// "tab": tabs.SHOP
// }
// }
// // sidebar state
// var currentState = scope.states.FLOORPLAN;
// function init() {
// for (var tab in tabs) {
// var elem = tabs[tab];
// elem.click(tabClicked(elem));
// }
// $("#update-floorplan").click(floorplanUpdate);
// initLeftMenu();
// blueprint3d.three.updateWindowSize();
// handleWindowResize();
// initItems();
// setCurrentState(scope.states.DEFAULT);
// }
// function floorplanUpdate() {
// setCurrentState(scope.states.DEFAULT);
// }
// function tabClicked(tab) {
// return function () {
// // Stop three from spinning
// blueprint3d.three.stopSpin();
// // Selected a new tab
// for (var key in scope.states) {
// var state = scope.states[key];
// if (state.tab == tab) {
// setCurrentState(state);
// break;
// }
// }
// }
// }
// function setCurrentState(newState) {
// if (currentState == newState) {
// return;
// }
// // show the right tab as active
// if (currentState.tab !== newState.tab) {
// if (currentState.tab != null) {
// currentState.tab.removeClass(ACTIVE_CLASS);
// }
// if (newState.tab != null) {
// newState.tab.addClass(ACTIVE_CLASS);
// }
// }
// // set item unselected
// blueprint3d.three.getController().setSelectedObject(null);
// // show and hide the right divs
// currentState.div.hide()
// newState.div.show()
// // custom actions
// if (newState == scope.states.FLOORPLAN) {
// floorplanControls.updateFloorplanView();
// floorplanControls.handleWindowResize();
// }
// if (currentState == scope.states.FLOORPLAN) {
// blueprint3d.model.floorplan.update();
// }
// if (newState == scope.states.DEFAULT) {
// blueprint3d.three.updateWindowSize();
// }
// // set new state
// handleWindowResize();
// currentState = newState;
// scope.stateChangeCallbacks.fire(newState);
// }
// function initLeftMenu() {
// $(window).resize(handleWindowResize);
// handleWindowResize();
// }
// function handleWindowResize() {
// $(".sidebar").height(window.innerHeight);
// $("#add-items").height(window.innerHeight);
// };
// // TODO: this doesn't really belong here
// function initItems() {
// $("#add-items").find(".add-item").mousedown(function (e) {
// var modelUrl = $(this).attr("model-url");
// var itemType = parseInt($(this).attr("model-type"));
// var metadata = {
// itemName: $(this).attr("model-name"),
// resizable: true,
// modelUrl: modelUrl,
// itemType: itemType
// }
// blueprint3d.model.scene.addItem(itemType, modelUrl, metadata);
// setCurrentState(scope.states.DEFAULT);
// });
// }
// init();
// }
// /*
// * Change floor and wall textures
// */
// TextureSelector(blueprint3d, sideMenu) {
// var scope = this;
// var three = blueprint3d.three;
// var isAdmin = isAdmin;
// var currentTarget = null;
// function initTextureSelectors() {
// $(".texture-select-thumbnail").click(function (e) {
// var textureUrl = $(this).attr("texture-url");
// var textureStretch = ($(this).attr("texture-stretch") == "true");
// var textureScale = parseInt($(this).attr("texture-scale"));
// currentTarget.setTexture(textureUrl, textureStretch, textureScale);
// e.preventDefault();
// });
// }
// function init() {
// three.wallClicked.add(wallClicked);
// three.floorClicked.add(floorClicked);
// three.itemSelectedCallbacks.add(reset);
// three.nothingClicked.add(reset);
// sideMenu.stateChangeCallbacks.add(reset);
// initTextureSelectors();
// }
// function wallClicked(halfEdge) {
// currentTarget = halfEdge;
// $("#floorTexturesDiv").hide();
// $("#wallTextures").show();
// }
// function floorClicked(room) {
// currentTarget = room;
// $("#wallTextures").hide();
// $("#floorTexturesDiv").show();
// }
// function reset() {
// $("#wallTextures").hide();
// $("#floorTexturesDiv").hide();
// }
// init();
// }
// /*
// * Floorplanner controls
// */
// ViewerFloorplanner(blueprint3d) {
// var canvasWrapper = '#floorplanner';
// // buttons
// var move = '#move';
// var remove = '#delete';
// var draw = '#draw';
// var activeStlye = 'btn-primary disabled';
// this.floorplanner = blueprint3d.floorplanner;
// var scope = this;
// function init() {
// $(window).resize(scope.handleWindowResize);
// scope.handleWindowResize();
// // mode buttons
// scope.floorplanner.modeResetCallbacks.add(function (mode) {
// $(draw).removeClass(activeStlye);
// $(remove).removeClass(activeStlye);
// $(move).removeClass(activeStlye);
// if (mode == BP3D.Floorplanner.floorplannerModes.MOVE) {
// $(move).addClass(activeStlye);
// } else if (mode == BP3D.Floorplanner.floorplannerModes.DRAW) {
// $(draw).addClass(activeStlye);
// } else if (mode == BP3D.Floorplanner.floorplannerModes.DELETE) {
// $(remove).addClass(activeStlye);
// }
// if (mode == BP3D.Floorplanner.floorplannerModes.DRAW) {
// $("#draw-walls-hint").show();
// scope.handleWindowResize();
// } else {
// $("#draw-walls-hint").hide();
// }
// });
// $(move).click(function () {
// scope.floorplanner.setMode(BP3D.Floorplanner.floorplannerModes.MOVE);
// });
// $(draw).click(function () {
// scope.floorplanner.setMode(BP3D.Floorplanner.floorplannerModes.DRAW);
// });
// $(remove).click(function () {
// scope.floorplanner.setMode(BP3D.Floorplanner.floorplannerModes.DELETE);
// });
// }
// this.updateFloorplanView = function () {
// scope.floorplanner.reset();
// }
// this.handleWindowResize = function () {
// $(canvasWrapper).height(window.innerHeight - $(canvasWrapper).offset().top);
// scope.floorplanner.resizeView();
// };
// init();
// };
// mainControls(blueprint3d) {
// var blueprint3d = blueprint3d;
// function newDesign() {
// blueprint3d.model.loadSerialized('{"floorplan":{"corners":{"f90da5e3-9e0e-eba7-173d-eb0b071e838e":{"x":204.85099999999989,"y":289.052},"da026c08-d76a-a944-8e7b-096b752da9ed":{"x":672.2109999999999,"y":289.052},"4e3d65cb-54c0-0681-28bf-bddcc7bdb571":{"x":672.2109999999999,"y":-178.308},"71d4f128-ae80-3d58-9bd2-711c6ce6cdf2":{"x":204.85099999999989,"y":-178.308}},"walls":[{"corner1":"71d4f128-ae80-3d58-9bd2-711c6ce6cdf2","corner2":"f90da5e3-9e0e-eba7-173d-eb0b071e838e","frontTexture":{"url":"rooms/textures/wallmap.png","stretch":true,"scale":0},"backTexture":{"url":"rooms/textures/wallmap.png","stretch":true,"scale":0}},{"corner1":"f90da5e3-9e0e-eba7-173d-eb0b071e838e","corner2":"da026c08-d76a-a944-8e7b-096b752da9ed","frontTexture":{"url":"rooms/textures/wallmap.png","stretch":true,"scale":0},"backTexture":{"url":"rooms/textures/wallmap.png","stretch":true,"scale":0}},{"corner1":"da026c08-d76a-a944-8e7b-096b752da9ed","corner2":"4e3d65cb-54c0-0681-28bf-bddcc7bdb571","frontTexture":{"url":"rooms/textures/wallmap.png","stretch":true,"scale":0},"backTexture":{"url":"rooms/textures/wallmap.png","stretch":true,"scale":0}},{"corner1":"4e3d65cb-54c0-0681-28bf-bddcc7bdb571","corner2":"71d4f128-ae80-3d58-9bd2-711c6ce6cdf2","frontTexture":{"url":"rooms/textures/wallmap.png","stretch":true,"scale":0},"backTexture":{"url":"rooms/textures/wallmap.png","stretch":true,"scale":0}}],"wallTextures":[],"floorTextures":{},"newFloorTextures":{}},"items":[]}');
// }
// function loadDesign() {
// files = $("#loadFile").get(0).files;
// var reader = new FileReader();
// reader.onload = function (event) {
// var data = event.target.result;
// blueprint3d.model.loadSerialized(data);
// }
// reader.readAsText(files[0]);
// }
// function saveDesign() {
// var data = blueprint3d.model.exportSerialized();
// var a = window.document.createElement('a');
// var blob = new Blob([data], { type: 'text' });
// a.href = window.URL.createObjectURL(blob);
// a.download = 'design.blueprint3d';
// document.body.appendChild(a)
// a.click();
// document.body.removeChild(a)
// }
// function init() {
// $("#new").click(newDesign);
// $("#loadFile").change(loadDesign);
// $("#saveFile").click(saveDesign);
// }
// init();
// }
/*
* Initialize!
*/
Initialize() {
// main setup
// var opts = {
// floorplannerElement: 'floorplanner-canvas',
// threeElement: '#viewer',
// threeCanvasElement: 'three-canvas',
// textureDir: "models/textures/",
// widget: false
// }
// var blueprint3d = new BP3D.Blueprint3d(opts);
// var modalEffects = new ModalEffects(blueprint3d);
// var viewerFloorplanner = new ViewerFloorplanner(blueprint3d);
// var contextMenu = new ContextMenu(blueprint3d);
// var sideMenu = new SideMenu(blueprint3d, viewerFloorplanner, modalEffects);
// var textureSelector = new TextureSelector(blueprint3d, sideMenu);
// var cameraButtons = new CameraButtons(blueprint3d);
// mainControls(blueprint3d);
// // This serialization format needs work
// // Load a simple rectangle room
// blueprint3d.model.loadSerialized('{"floorplan":{"corners":{"f90da5e3-9e0e-eba7-173d-eb0b071e838e":{"x":204.85099999999989,"y":289.052},"da026c08-d76a-a944-8e7b-096b752da9ed":{"x":672.2109999999999,"y":289.052},"4e3d65cb-54c0-0681-28bf-bddcc7bdb571":{"x":672.2109999999999,"y":-178.308},"71d4f128-ae80-3d58-9bd2-711c6ce6cdf2":{"x":204.85099999999989,"y":-178.308}},"walls":[{"corner1":"71d4f128-ae80-3d58-9bd2-711c6ce6cdf2","corner2":"f90da5e3-9e0e-eba7-173d-eb0b071e838e","frontTexture":{"url":"rooms/textures/wallmap.png","stretch":true,"scale":0},"backTexture":{"url":"rooms/textures/wallmap.png","stretch":true,"scale":0}},{"corner1":"f90da5e3-9e0e-eba7-173d-eb0b071e838e","corner2":"da026c08-d76a-a944-8e7b-096b752da9ed","frontTexture":{"url":"rooms/textures/wallmap.png","stretch":true,"scale":0},"backTexture":{"url":"rooms/textures/wallmap.png","stretch":true,"scale":0}},{"corner1":"da026c08-d76a-a944-8e7b-096b752da9ed","corner2":"4e3d65cb-54c0-0681-28bf-bddcc7bdb571","frontTexture":{"url":"rooms/textures/wallmap.png","stretch":true,"scale":0},"backTexture":{"url":"rooms/textures/wallmap.png","stretch":true,"scale":0}},{"corner1":"4e3d65cb-54c0-0681-28bf-bddcc7bdb571","corner2":"71d4f128-ae80-3d58-9bd2-711c6ce6cdf2","frontTexture":{"url":"rooms/textures/wallmap.png","stretch":true,"scale":0},"backTexture":{"url":"rooms/textures/wallmap.png","stretch":true,"scale":0}}],"wallTextures":[],"floorTextures":{},"newFloorTextures":{}},"items":[]}');
}
}

0
src/assets/.gitkeep

BIN
src/assets/GPC/CarColor.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
src/assets/GPC/FireCar.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 KiB

BIN
src/assets/GPC/GPC.bin

Binary file not shown.

2750
src/assets/GPC/GPC.gltf

File diff suppressed because it is too large Load Diff

0
src/blueprint/blueprint.component.css

4
src/blueprint/blueprint.component.html

@ -0,0 +1,4 @@
<div id="bp3d-js-app">
<div id="bp3djs-viewer2d"></div>
<div id="bp3djs-viewer3d"></div>
</div>

25
src/blueprint/blueprint.component.spec.ts

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { BlueprintComponent } from './blueprint.component';
describe('BlueprintComponent', () => {
let component: BlueprintComponent;
let fixture: ComponentFixture<BlueprintComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ BlueprintComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(BlueprintComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

56
src/blueprint/blueprint.component.ts

@ -0,0 +1,56 @@
import { Component, OnInit } from '@angular/core';
import { BlueprintJS, BlueprintOptions } from './scripts/blueprint';
@Component({
selector: 'app-blueprint',
templateUrl: './blueprint.component.html',
styleUrls: ['./blueprint.component.css']
})
export class BlueprintComponent implements OnInit {
blueprint3d: BlueprintJS;
constructor() { }
ngOnInit(): void {
let opts: BlueprintOptions = {
viewer2d: {
id: 'bp3djs-viewer2d',
viewer2dOptions: {
'corner-radius': 12.5,
'boundary-point-radius': 5.0,
'boundary-line-thickness': 2.0,
'boundary-point-color': '#030303',
'boundary-line-color': '#090909',
pannable: true,
zoomable: true,
scale: false,
rotate: true,
translate: true,
dimlinecolor: '#3E0000',
dimarrowcolor: '#FF0000',
dimtextcolor: '#000000',
pixiAppOptions: {
resolution: 1,
},
pixiViewportOptions: {
passiveWheel: false,
}
},
},
viewer3d: {
id: 'bp3djs-viewer3d',
viewer3dOptions: {
occludedWalls: false,
occludedRoofs: false
}
},
textureDir: "models/textures/",
widget: false,
resize: true,
};
this.blueprint3d = new BlueprintJS(opts);
}
}

53
src/blueprint/scripts/ParametricsInterface.js

@ -0,0 +1,53 @@
import QuickSettings from 'quicksettings';
export class ParametricsInterface {
constructor(parametricDataClass, viewer3D, x = 0, y = 0, appParent = null) {
this.__parametricDataClass = parametricDataClass;
this.__viewer3D = viewer3D;
this.__settings = QuickSettings.create(x, y, `Parametric Item: ${parametricDataClass.name}`, appParent);
this.__constructUI();
}
__constructUI() {
let parameters = this.__parametricDataClass.parameters;
let parametricsClass = this.__parametricDataClass;
let viewer3D = this.__viewer3D;
for (let opt in parameters) {
let property = parameters[opt];
switch (property.type) {
case 'color':
this.__settings.addColor(opt, parametricsClass[opt], function(value) {
parametricsClass[opt] = value;
viewer3D.needsUpdate = true;
});
break;
case 'number':
this.__settings.addNumber(opt, 10, 5000, parametricsClass[opt], 1, function(value) {
parametricsClass[opt] = value;
viewer3D.needsUpdate = true;
});
break;
case 'range':
this.__settings.addRange(opt, property.min, property.max, parametricsClass[opt], property.step, function(value) {
parametricsClass[opt] = value;
viewer3D.needsUpdate = true;
});
break;
case 'choice':
this.__settings.addDropDown(opt, property.value, function(item) {
parametricsClass[opt] = item.value;
viewer3D.needsUpdate = true;
});
break;
default:
console.log('YET TO IMPLEMENT');
}
}
}
destroy() {
if (this.__settings) {
this.__settings.destroy();
}
}
}

139
src/blueprint/scripts/blueprint.ts

@ -0,0 +1,139 @@
import { Configuration, configDimUnit } from "./core/configuration";
import { dimCentiMeter } from "./core/constants";
import { Model } from "./model/model";
import { Viewer3D } from "./viewer3d/Viewer3d";
import { Viewer2D, floorplannerModes } from "./viewer2d/Viewer2D";
import { ConfigurationHelper } from "./helpers/ConfigurationHelper";
import { FloorPlannerHelper } from "./helpers/FloorplannerHelper";
import { RoomPlannerHelper } from "./helpers/RoomplannerHelper";
export type BlueprintOptions = {
viewer2d: {
id: string,
viewer2dOptions: {
'corner-radius': number,
'boundary-point-radius': number,
'boundary-line-thickness': number,
'boundary-point-color': string,
'boundary-line-color': string,
pannable: boolean,
zoomable: boolean,
scale: boolean,
rotate: boolean,
translate: boolean,
dimlinecolor: string,
dimarrowcolor: string,
dimtextcolor: string,
pixiAppOptions: {
resolution: number,
},
pixiViewportOptions: {
passiveWheel: boolean,
},
},
},
viewer3d: {
id: string,
viewer3dOptions: {
occludedWalls: boolean,
occludedRoofs: boolean,
}
},
textureDir: string,
widget: boolean,
resize: boolean,
}
/**
*
*/
export class BlueprintJS {
options: BlueprintOptions;
model: Model;
roomplanner: Viewer3D;
configurationHelper: ConfigurationHelper;
floorplanningHelper: FloorPlannerHelper;
roomplanningHelper: RoomPlannerHelper;
viewer2d: Viewer2D;
viewer3d: Viewer3D;
view_now: number;
/**
*
* @例子
* blueprint3d = new BP3DJS.BlueprintJS(opts);
*/
constructor(options: BlueprintOptions) {
Configuration.setValue(configDimUnit, dimCentiMeter);
this.options = options;
this.model = new Model(options.textureDir);
let viewer3dOptions = this.options.viewer3d.viewer3dOptions;
// viewer3dOptions.resize = (this.options.resize) ? true : false;
this.roomplanner = new Viewer3D(this.model, options.viewer3d.id, viewer3dOptions);
this.configurationHelper = new ConfigurationHelper();
this.floorplanningHelper = null;
this.roomplanningHelper = new RoomPlannerHelper(this.model, this.model.floorplan, this.roomplanner);
if (!options.widget) {
let viewer2dOptions = this.options.viewer2d.viewer2dOptions;
// viewer2dOptions.resize = (this.options.resize) ? true : false;
this.viewer2d = new Viewer2D(options.viewer2d.id, this.model.floorplan, viewer2dOptions);
this.floorplanningHelper = new FloorPlannerHelper(this.model.floorplan, this.viewer2d);
}
this.view_now = 3;
this.switchView();
}
switchView(): void {
if (this.options.widget) {
return;
}
this.viewer2d.switchMode(floorplannerModes.MOVE);
if (this.view_now === 3 && !this.options.widget) {
this.view_now = 2;
document.getElementById(this.options.viewer2d.id).style.visibility = "visible";
document.getElementById(this.options.viewer3d.id).style.visibility = "hidden";
this.roomplanner.enabled = false;
} else if (this.view_now === 2 && !this.options.widget) {
this.view_now = 3;
document.getElementById(this.options.viewer2d.id).style.visibility = "hidden";
document.getElementById(this.options.viewer3d.id).style.visibility = "visible";
this.roomplanner.enabled = true;
}
}
setViewer2DModeToDraw(mode) {
if (this.options.widget) {
return;
}
this.viewer2d.switchMode(floorplannerModes.DRAW);
}
setViewer2DModeToMove(mode) {
if (this.options.widget) {
return;
}
this.viewer2d.switchMode(floorplannerModes.MOVE);
}
switchViewer2DToTransform(mode) {
if (this.options.widget) {
return;
}
this.viewer2d.switchMode(floorplannerModes.EDIT_ISLANDS);
}
updateView3D() {
this.viewer3d.needsUpdate = true;
}
get currentView() {
return this.view_now;
}
}

83
src/blueprint/scripts/core/EventSystem.ts

@ -0,0 +1,83 @@
import { MessageSystem } from "./MessageSystem";
export type eventTypes =
"ACTION_EVENT" |
"DELETED_EVENT" |
"MOVED_EVENT" |
"REDRAW_EVENT" |
"NEW_EVENT" |
"LOADED_EVENT" |
"LOADING_EVENT" |
"UPDATED_EVENT" |
"SAVED_EVENT" |
"CHANGED_EVENT" |
"GLTF_READY_EVENT" |
"EXTERNAL_FLOORPLAN_LOADED_EVENT" |
"NEW_PARAMETRIC_ITEM_EVENT" |
"NEW_ITEM_EVENT" |
"ITEM_LOADING_EVENT" |
"ITEM_LOADED_EVENT" |
"ITEM_REMOVED_EVENT" |
"ITEM_SELECTED_EVENT" |
"ITEM_MOVED_EVENT" |
"ITEM_MOVED_FINISH_EVENT" |
"ITEM_HOVERON_EVENT" |
"ITEM_HOVEROFF_EVENT" |
"ITEM_NO_SELECTED_EVENT" |
"MODE_RESET_EVENT" |
"CAMERA_MOVED_EVENT" |
"CAMERA_ACTIVE_STATUS_EVENT" |
"CAMERA_VIEW_CHANGE_EVENT" |
"CAMERA_FPS_EXIT_EVENT" |
"WALL_CLICKED_EVENT" |
"ROOM_CLICKED_EVENT" |
"FLOOR_CLICKED_EVENT" |
"NOTHING_CLICKED_EVENT" |
"CHANGED_ROOM_NAME_EVENT" |
"ADDED_NEW_ROOMS_EVENT" |
"CORNER_ATTRIBUTES_CHANGED_EVENT" |
"WALL_ATTRIBUTES_CHANGED_EVENT" |
"ROOM_ATTRIBUTES_CHANGED_EVENT" |
"CORNER_CLICKED_2D_EVENT" |
"WALL_CLICKED_2D_EVENT" |
"ROOM_CLICKED_2D_EVENT" |
"UNSELECTED_2D_EVENT" |
"SELECTED_2D_EVENT" |
"NOTHING_2D_SELECTED_EVENT" |
"CORNER_DOUBLE_CLICKED_2D_EVENT" |
"WALL_DOUBLE_CLICKED_2D_EVENT" |
"ROOM_DOUBLE_CLICKED_2D_EVENT" |
"CORNER_HOVER_2D_EVENT" |
"WALL_HOVER_2D_EVENT" |
"ROOM_HOVER_2D_EVENT" |
"KEY_PRESSED_EVENT" |
"KEY_RELEASED_EVENT" |
"UPDATE_TEXTURES_EVENT" |
"MODIFY_TEXTURE_ATTRIBUTE_EVENT" |
"PARAMETRIC_GEOMETRY_UPATED_EVENT" |
"BOUNDARY_UPDATE_EVENT"
;
export class EventSystem extends MessageSystem<eventTypes, Object>{
private static instance: EventSystem = new EventSystem();
private constructor() {
super();
}
public static get Instance(): EventSystem {
return this.instance;
}
}

205
src/blueprint/scripts/core/MessageSystem.ts

@ -0,0 +1,205 @@
/**
*
*
* interface Event {
type: eventTypes;
eventData: unknown;
}
type eventTypes = "a" | "b";
const msg = new MessageSystem<eventTypes, Event>();
const event = (event1:Event) => {
console.log(event1.eventData);
}
msg.addListener("a", event);
msg.sendMessage("a", { type: "a", eventData: "注册发送" });
msg.removeListener("a", event)
msg.sendMessage("a", { type: "a", eventData: "移除消息后发送" });
*
*
*
*
*/
export class MessageSystem<T, V> {
// 监听对象
private Observables: Map<T, Observable<V>> = new Map<T, Observable<V>>();
constructor() {
}
/**
*
* @param eventType
* @param callback
* @returns
*/
public addListener(eventType: T, callback: (eventData: V) => void): Observer<V> {
let observable: Observable<V> = null;
// 如果没有观察者,添加观察者
if (this.Observables.has(eventType)) {
observable = this.Observables.get(eventType);
} else {
observable = new Observable<V>();
this.Observables.set(eventType, observable);
}
return observable.addCallback(callback);
}
public removeListener(eventType: T, callback: (eventData: V) => void): boolean {
let observable: Observable<V> = null;
// 如果没有观察者,返回
if (this.Observables.has(eventType)) {
observable = this.Observables.get(eventType);
const result = observable.removeCallback(callback);
if (!observable.hasObservers()) {
this.Observables.delete(eventType);
}
return result;
} else {
return false;
}
}
public sendMessage(eventType: T, eventData: V): boolean {
let observable: Observable<V> = null;
if (this.Observables.has(eventType)) {
observable = this.Observables.get(eventType);
return observable.notifyObservers(eventData);
} else {
return false;
}
}
}
/**
*
*/
class Observable<T>{
private _observers: Array<Observer<T>>;
private _onObserverAdded: (observer: Observer<T>) => void;
get observers(): Array<Observer<T>> {
return this._observers;
}
constructor(onObserverAdded?: (observer: Observer<T>) => void) {
this._observers = new Array<Observer<T>>();
if (onObserverAdded) {
this._onObserverAdded = onObserverAdded;
}
}
/**
*
* @param observer
* @returns
*/
add(observer: Observer<T>): boolean {
if (!observer) {
return false;
}
this._observers.push(observer);
if (this._onObserverAdded) {
this._onObserverAdded(observer);
}
return true;
}
/**
*
* @param callback
* @returns
*/
addCallback(callback: (eventData: T) => void): Observer<T> {
if (!callback) {
return null;
}
const observer = new Observer(callback);
this.add(observer);
return observer;
}
/**
*
* @param observer
* @returns
*/
remove(observer: Observer<T>): boolean {
if (!observer) {
return false;
}
var index = this._observers.indexOf(observer);
if (index !== -1) {
this._observers.splice(index, 1);
return true;
}
return false;
}
/**
*
* @param callback
* @returns true false
*/
removeCallback(callback: (eventData: T) => void): boolean {
for (var index = 0; index < this._observers.length; index++) {
var observer = this._observers[index];
if (observer.compar(callback)) {
this.remove(observer);
return true;
}
}
return false;
}
/**
*
* @param eventData
* @returns 成功: true false
*/
notifyObservers(eventData: T): boolean {
if (!this._observers.length) {
return true;
}
for (const observer of this._observers) {
observer.notify(eventData);
}
return true;
}
/**
*
* @returns 成功: true false
*/
hasObservers(): boolean {
return this._observers.length > 0;
}
/**
*
*/
clear(): void {
this._observers = new Array<Observer<T>>();
this._onObserverAdded = null;
}
}
/**
*
*/
class Observer<T> {
private callback: (event: T) => void = null;
constructor(callback: (event: T) => void) {
this.callback = callback;
}
notify(event: T): void {
this.callback(event);
}
compar(callback: (event: T) => void): boolean {
return callback === this.callback;
}
}

32
src/blueprint/scripts/core/Singleton.ts

@ -0,0 +1,32 @@
/**
* 饿
*
*/
class SingletonMode1 {
private static instance = new SingletonMode1()
// 将 constructor 设为私有属性,防止 new 调用
private constructor() { }
static getInstance(): SingletonMode1 {
return this.instance
}
}
/**
*
*
*/
class SingletonMode2 {
private static instance: SingletonMode2
private constructor() { }
static getInstance(): SingletonMode2 {
if (!this.instance) {
this.instance = new SingletonMode2()
}
return this.instance
}
}

122
src/blueprint/scripts/core/configuration.ts

@ -0,0 +1,122 @@
import { dimCentiMeter } from './constants.js';
import { EventSystem, eventTypes } from './EventSystem.js';
// GENERAL:
/** The dimensioning unit for 2D floorplan measurements. */
export var configDimUnit = 'dimUnit';
// WALL:
/** The initial wall height in cm. */
export const configWallHeight = 'wallHeight';
/** The initial wall thickness in cm. */
export const configWallThickness = 'wallThickness';
export const configSystemUI = 'systemUI';
export const scale = 'scale';
export const gridSpacing = 'gridSpacing';
export const snapToGrid = 'snapToGrid';
export const directionalDrag = 'directionalDrag';
export const dragOnlyX = 'dragOnlyX';
export const dragOnlyY = 'dragOnlyY';
export const snapTolerance = 'snapTolerance'; //In CMS
export const boundsX = 'boundsX'; //In CMS
export const boundsY = 'boundsY'; //In CMS
export const viewBounds = 'viewBounds';//In CMS
export var config = {
dimUnit: dimCentiMeter, wallHeight: 250,
wallThickness: 20, systemUI: false,
scale: 1, snapToGrid: true,
dragOnlyX: false, dragOnlyY: false,
snapTolerance: 50, gridSpacing: 50,
directionalDrag: true,
boundsX: 500, boundsY: 500,
viewBounds: 5000
};
export var wallInformation = { exterior: false, interior: false, midline: true, labels: true, exteriorlabel: 'e:', interiorlabel: 'i:', midlinelabel: 'm:' };
/**
* The tolerance in cms between corners, otherwise below this tolerance they will snap together as one corner*/
export const cornerTolerance = 20;
/** Global configuration to customize the whole system.
* This is a singleton instance;
*/
export class Configuration {
private static instance: Configuration;
constructor() {
/** Configuration data loaded from/stored to extern. */
// this.data = {dimUnit: dimCentiMeter, wallHeight: 250, wallThickness: 10};
}
static getInstance() {
if (this.instance === undefined) {
this.instance = new Configuration();
}
return this.instance;
}
static getData() {
// return {dimUnit: dimCentiMeter,wallHeight: 250, wallThickness: 10};
return config;
}
/** Set a configuration parameter. */
static setValue(key, value) {
// this.data[key] = value;
config[key] = value;
// if(key !== viewBounds){
// Configuration.getInstance().dispatchEvent({ type: EVENT_CHANGED, item: Configuration.getInstance(), 'key': key, 'value': value });
EventSystem.Instance.sendMessage("CHANGED_EVENT", {});
// }
}
/** Get a string configuration parameter. */
static getStringValue(key): string {
switch (key) {
case configDimUnit:
// return String(this.data[key]);
return String(Configuration.getData()[key]);
default:
throw new Error('Invalid string configuration parameter: ' + key);
}
}
/** Get a numeric configuration parameter. */
static getNumericValue(key): number {
switch (key) {
case configSystemUI:
case configWallHeight:
case configWallThickness:
case scale:
case snapTolerance:
case gridSpacing:
case boundsX:
case boundsY:
case viewBounds:
// return Number(this.data[key]);
return Number(Configuration.getData()[key]);
default:
throw new Error('Invalid numeric configuration parameter: ' + key);
}
}
/** Get a numeric configuration parameter. */
static getBooleanValue(key): boolean {
switch (key) {
case snapToGrid:
case directionalDrag:
case dragOnlyX:
case dragOnlyY:
return Boolean(Configuration.getData()[key]);
default:
throw new Error('Invalid Boolean configuration parameter: ' + key);
}
}
}

32
src/blueprint/scripts/core/constants.ts

@ -0,0 +1,32 @@
/** Dimensioning in Inch. */
export const dimInch = 'inch';
/** Dimensioning in Inch. */
export const dimFeetAndInch = 'feetAndInch';
/** Dimensioning in Meter. */
export const dimMeter = 'm';
/** Dimensioning in Centi Meter. */
export const dimCentiMeter = 'cm';
/** Dimensioning in Milli Meter. */
export const dimMilliMeter = 'mm';
export const VIEW_TOP = 'topview';
export const VIEW_FRONT = 'frontview';
export const VIEW_RIGHT = 'rightview';
export const VIEW_LEFT = 'leftview';
export const VIEW_ISOMETRY = 'isometryview';
export enum WallTypes {
STRAIGHT,
CURVED
}
export const TEXTURE_DEFAULT_REPEAT = 300;
export const defaultWallTexture = { color: '#FFFFFF', repeat: TEXTURE_DEFAULT_REPEAT, normalmap: 'textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg', roughnessmap: 'textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg', colormap: 'textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg', ambientmap: 'textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg', bumpmap: 'textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png' };
export const defaultFloorTexture = { color: '#FFFFFF', emissive: '#181818', repeat: TEXTURE_DEFAULT_REPEAT, ambientmap: 'textures/Floor/Marble_Tiles_001/Marble_Tiles_001_ambientOcclusion.jpg', colormap: 'textures/Floor/Marble_Tiles_001/Marble_Tiles_001_basecolor.jpg', roughnessmap: 'textures/Floor/Marble_Tiles_001/Marble_Tiles_001_roughness.jpg', normalmap: 'textures/Floor/Marble_Tiles_001/Marble_Tiles_001_normal.jpg' };
export const TEXTURE_PROPERTY_COLOR = 'color';
export const TEXTURE_NO_PREVIEW = 'textures/NoPreview.jpg';

146
src/blueprint/scripts/core/dimensioning.ts

@ -0,0 +1,146 @@
import { Vector2, Vector3 } from 'three';
import { Configuration, configDimUnit } from './configuration.js';
import { dimInch, dimFeetAndInch, dimMeter, dimCentiMeter, dimMilliMeter } from './constants.js';
export const decimals = 1000;
export const cmPerFoot = 30.48;
export const pixelsPerFoot = 5.0;
export const pixelsPerCm = 0.5;
export const cmPerPixel = (1.0 / pixelsPerCm);
export const dimensioningOptions = [dimInch, dimFeetAndInch, dimMeter, dimCentiMeter, dimMilliMeter];
/** Dimensioning functions. */
export class Dimensioning {
static cmToPixelVector2D(cmV2d) {
let pixelV2d = new Vector2(Dimensioning.cmToPixel(cmV2d.x), Dimensioning.cmToPixel(cmV2d.y));
return pixelV2d;
}
static cmToPixelVector3D(cmV3d) {
let pixelV2d = new Vector3(Dimensioning.cmToPixel(cmV3d.x), Dimensioning.cmToPixel(cmV3d.y), Dimensioning.cmToPixel(cmV3d.z));
return pixelV2d;
}
static pixelToCmVector2D(pixelV2d) {
let cmV2d = new Vector2(Dimensioning.cmToPixel(pixelV2d.x), Dimensioning.cmToPixel(pixelV2d.y));
return cmV2d;
}
static pixelToCmVector3D(pixel3d) {
let cmV2d = new Vector3(Dimensioning.cmToPixel(pixel3d.x), Dimensioning.cmToPixel(pixel3d.y), Dimensioning.cmToPixel(pixel3d.z));
return cmV2d;
}
static cmToPixel(cm, apply_scale = true) {
if (apply_scale) {
return cm * pixelsPerCm * Configuration.getNumericValue('scale');
}
return cm * pixelsPerCm;
}
static pixelToCm(pixel, apply_scale = true) {
if (apply_scale) {
return pixel * cmPerPixel * (1.0 / Configuration.getNumericValue('scale'));
}
return pixel * cmPerPixel;
}
static roundOff(value, decimals) {
return Math.round(decimals * value) / decimals;
}
/** Converts cm to dimensioning number.
* @param cm Centi meter value to be converted.
* @returns Number representation.
*/
static cmFromMeasureRaw(measure) {
switch (Configuration.getStringValue(configDimUnit)) {
case dimFeetAndInch:
return Math.round(decimals * (measure * 30.480016459203095991)) / decimals;
case dimInch:
return Math.round(decimals * (measure * 2.5400013716002578512)) / decimals;
case dimMilliMeter:
return Math.round(decimals * (measure * 0.10000005400001014955)) / decimals;
case dimCentiMeter:
return measure;
case dimMeter:
default:
return Math.round(decimals * 100 * measure) / decimals;
}
}
/** Converts cm to dimensioning string.
* @param cm Centi meter value to be converted.
* @returns String representation.
*/
static cmFromMeasure(measure) {
switch (Configuration.getStringValue(configDimUnit)) {
case dimFeetAndInch:
return Math.round(decimals * (measure * 30.480016459203095991)) / decimals + 'cm';
case dimInch:
return Math.round(decimals * (measure * 2.5400013716002578512)) / decimals + 'cm';
case dimMilliMeter:
return Math.round(decimals * (measure * 0.10000005400001014955)) / decimals + 'cm';
case dimCentiMeter:
return measure;
case dimMeter:
default:
return Math.round(decimals * 100 * measure) / decimals + 'cm';
}
}
/** Converts cm to dimensioning string.
* @param cm Centi meter value to be converted.
* @returns String representation.
*/
static cmToMeasureRaw(cm, power = 1) {
switch (Configuration.getStringValue(configDimUnit)) {
case dimFeetAndInch: // dimFeetAndInch returns only the feet
var allInFeet = (cm * Math.pow(0.032808416666669996953, power));
return allInFeet;
case dimInch:
var inches = Math.round(decimals * (cm * Math.pow(0.393700, power))) / decimals;
return inches;
case dimMilliMeter:
var mm = Math.round(decimals * (cm * Math.pow(10, power))) / decimals;
return mm;
case dimCentiMeter:
return Math.round(decimals * cm) / decimals;
case dimMeter:
default:
var m = Math.round(decimals * (cm * Math.pow(0.01, power))) / decimals;
return m;
}
}
/** Converts cm to dimensioning string.
* @param cm Centi meter value to be converted.
* @returns String representation.
*/
static cmToMeasure(cm, power = 1) {
switch (Configuration.getStringValue(configDimUnit)) {
case dimFeetAndInch:
var allInFeet = (cm * Math.pow(0.032808416666669996953, power));
var floorFeet = Math.floor(allInFeet);
var remainingFeet = allInFeet - floorFeet;
var remainingInches = Math.round(remainingFeet * 12);
return floorFeet + '\'' + remainingInches + '';
case dimInch:
var inches = Math.round(decimals * (cm * Math.pow(0.393700, power))) / decimals;
return inches + '\'';
case dimMilliMeter:
var mm = Math.round(decimals * (cm * Math.pow(10, power))) / decimals;
return '' + mm + 'mm';
case dimCentiMeter:
return '' + Math.round(decimals * cm) / decimals + 'cm';
case dimMeter:
default:
var m = Math.round(decimals * (cm * Math.pow(0.01, power))) / decimals;
return '' + m + 'm';
}
}
}

14
src/blueprint/scripts/core/exposable.ts

@ -0,0 +1,14 @@
export const GUI_TYPES = Enum('Boolean', 'Function', 'Color', 'Date', 'Array', 'HtmlElement', 'File', 'Html', 'Image', 'Number', 'String', 'Time');
export class GuiBindable extends EventDispatcher {
constructor(instance, property, guiObject) {
}
updateGUI() {
}
}

58
src/blueprint/scripts/core/log.ts

@ -0,0 +1,58 @@
export enum ELogContext {
None,
All,
Interaction2d,
Item,
Wall,
Room
}
export enum ELogLevel {
Information,
Warning,
Error,
Fatal,
Debug
}
/** The current log context. To be set when initializing the Application. */
export var logContext = ELogContext.None;
/** Pre-check if logging for specified context and/or level is enabled.
* This may be used to avoid compilation of complex logs.
* @param context The log context to be verified.
* @param level The log level to be verified.
* @returns If this context/levels is currently logged.
*/
export function isLogging(context, level) {
return logContext === ELogContext.All || logContext === context || level === ELogLevel.Warning || level === ELogLevel.Error || level === ELogLevel.Fatal;
}
/** Log the passed message in the context and with given level.
* @param context The context in which the message should be logged.
* @param level The level of the message.
* @param message The messages to be logged.
*/
export function log(context, level, message) {
if (isLogging(context, level) === false) {
return;
}
var tPrefix = '';
switch (level) {
case ELogLevel.Information:
tPrefix = '[INFO_] ';
break;
case ELogLevel.Warning:
tPrefix = '[WARNG] ';
break;
case ELogLevel.Error:
tPrefix = '[ERROR] ';
break;
case ELogLevel.Fatal:
tPrefix = '[FATAL] ';
break;
case ELogLevel.Debug:
tPrefix = '[DEBUG] ';
break;
}
console.log(tPrefix + message);
}

472
src/blueprint/scripts/core/utils.js

@ -0,0 +1,472 @@
import { Vector3, Vector2 } from 'three';
import { Math as THREEMath } from 'three';
import { checkIntersection } from 'line-intersect';
export class Utils {
/** Determines the distance of a point from a line.
* @param point The Point coordinates as THREE.Vector2
* @param start The starting coordinates of the line as THREE.Vector2
* @param end The ending coordinates of the line as THREE.Vector2
* @returns The distance value (number).
*/
static pointDistanceFromLine(point, start, end) {
var tPoint = Utils.closestPointOnLine(point, start, end);
var tDx = point.x - tPoint.x;
var tDy = point.y - tPoint.y;
return Math.sqrt(tDx * tDx + tDy * tDy);
}
/** Gets the projection of a point onto a line.
* @param point the point
* @param start the starting coordinates of the line as THREE.Vector2
* @param end the ending coordinates of the line as THREE.Vector2
* @returns The point as THREE.Vector2.
*/
static closestPointOnLine(point, start, end) {
// Inspired by: http://stackoverflow.com/a/6853926
var tA = point.x - start.x;
var tB = point.y - start.y;
var tC = end.x - start.x;
var tD = end.y - start.y;
var tDot = tA * tC + tB * tD;
var tLenSq = tC * tC + tD * tD;
var tParam = tDot / tLenSq;
var tXx, tYy;
if (tParam < 0 || (start.x === end.x && start.y === end.y)) {
tXx = start.x;
tYy = start.y;
} else if (tParam > 1) {
tXx = end.x;
tYy = end.y;
} else {
tXx = start.x + tParam * tC;
tYy = start.y + tParam * tD;
}
return new Vector2(tXx, tYy);
}
/** Gets the distance of two points.
* @param start the starting coordinate of the line as Vector2
* @param end the ending coordinate of the line as Vector2
* @returns The distance.
*/
static distance(start, end) {
return Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2));
}
/** Gets the angle between point1 -> start and 0,0 -> point2 (-pi to pi)
* @returns The angle.
*/
static angle(start, end) {
var tDot = start.x * end.x + start.y * end.y;
var tDet = start.x * end.y - start.y * end.x;
var tAngle = -Math.atan2(tDet, tDot);
return tAngle;
}
/** shifts angle to be 0 to 2pi */
static angle2pi(start, end) {
var tTheta = Utils.angle(start, end);
if (tTheta < 0) {
tTheta += 2.0 * Math.PI;
}
return tTheta;
}
/** shifts angle to be 0 to 2pi */
static getCyclicOrder(points, start = undefined) {
if (!start) {
start = new Vector2(0, 0);
}
var angles = [];
for (var i = 0; i < points.length; i++) {
var point = points[i];
var vect = point.clone().sub(start);
var radians = Math.atan2(vect.y, vect.x);
var degrees = THREEMath.radToDeg(radians);
degrees = (degrees > 0) ? degrees : (degrees + 360) % 360;
angles.push(degrees);
}
var indices = Utils.argsort(angles);
var sortedAngles = [];
var sortedPoints = [];
for (i = 0; i < indices.length; i++) {
sortedAngles.push(angles[indices[i]]);
sortedPoints.push(points[indices[i]]);
}
return { indices: indices, angles: sortedAngles, points: sortedPoints };
}
static argsort(numericalValues, direction = 1) {
var indices = Array.from(new Array(numericalValues.length), (val, index) => index);
return indices
.map((item, index) => [numericalValues[index], item]) // add the clickCount to sort by
.sort(([count1], [count2]) => (count1 - count2) * direction) // sort by the clickCount data
.map(([, item]) => item); // extract the sorted items
}
/** Checks if an array of points is clockwise.
* @param points Is array of points with x,y attributes
* @returns True if clockwise.
*/
static isClockwise(points) {
// make positive
let tSubX = Math.min(0, Math.min.apply(null, Utils.map(points, function(p) {
return p.x;
})));
let tSubY = Math.min(0, Math.min.apply(null, Utils.map(points, function(p) {
return p.x;
})));
var tNewPoints = Utils.map(points, function(p) {
return {
x: p.x - tSubX,
y: p.y - tSubY
};
});
// determine CW/CCW, based on:
// http://stackoverflow.com/questions/1165647
var tSum = 0;
for (var tI = 0; tI < tNewPoints.length; tI++) {
var tC1 = tNewPoints[tI];
var tC2;
if (tI === tNewPoints.length - 1) {
tC2 = tNewPoints[0];
} else {
tC2 = tNewPoints[tI + 1];
}
tSum += (tC2.x - tC1.x) * (tC2.y + tC1.y);
}
return (tSum >= 0);
}
/** Creates a Guide.
* @returns A new Guide.
*/
static guide() {
var tS4 = function() {
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
};
return tS4() + tS4() + '-' + tS4() + '-' + tS4() + '-' + tS4() + '-' + tS4() + tS4() + tS4();
}
/** both arguments are arrays of corners with x,y attributes */
static polygonPolygonIntersect(firstCorners, secondCorners) {
for (var tI = 0; tI < firstCorners.length; tI++) {
var tFirstCorner = firstCorners[tI],
tSecondCorner;
if (tI === firstCorners.length - 1) {
tSecondCorner = firstCorners[0];
} else {
tSecondCorner = firstCorners[tI + 1];
}
if (Utils.linePolygonIntersect(tFirstCorner.x, tFirstCorner.y, tSecondCorner.x, tSecondCorner.y, secondCorners)) {
return true;
}
}
return false;
}
/** Corners is an array of points with x,y attributes */
static linePolygonIntersect(point, point2, corners) {
for (var tI = 0; tI < corners.length; tI++) {
var tFirstCorner = corners[tI],
tSecondCorner;
if (tI === corners.length - 1) {
tSecondCorner = corners[0];
} else {
tSecondCorner = corners[tI + 1];
}
if (Utils.lineLineIntersect(point, point2, { x: tFirstCorner.x, y: tFirstCorner.y }, { x: tSecondCorner.x, y: tSecondCorner.y })) {
return true;
}
}
return false;
}
/** */
static lineLineIntersectPoint(aStart, aEnd, bStart, bEnd) {
var result = checkIntersection(aStart.x, aStart.y, aEnd.x, aEnd.y, bStart.x, bStart.y, bEnd.x, bEnd.y);
if (result.point) {
return new Vector2(result.point.x, result.point.y);
}
return undefined;
}
/** */
static lineLineIntersect(lineAStart, lineAEnd, lineBStart, lineBEnd) {
function tCCW(p1, p2, p3) {
var tA = p1.x,
tB = p1.y,
tC = p2.x,
tD = p2.y,
tE = p3.x,
tF = p3.y;
return (tF - tB) * (tC - tA) > (tD - tB) * (tE - tA);
}
var tP1 = lineAStart,
tP2 = lineAEnd,
tP3 = lineBStart,
tP4 = lineBEnd;
return (tCCW(tP1, tP3, tP4) != tCCW(tP2, tP3, tP4)) && (tCCW(tP1, tP2, tP3) != tCCW(tP1, tP2, tP4));
}
/**
@param corners Is an array of points with x,y attributes
@param startX X start coord for raycast
@param startY Y start coord for raycast
*/
static pointInPolygon2(point, polygon) {
var x = point.x,
y = point.y;
var inside = false;
for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
var intersect = ((((polygon[i].y <= y) && (y < polygon[j].y)) || ((polygon[j].y <= y) && (y < polygon[i].y))) && (x < (polygon[j].x - polygon[i].x) * (y - polygon[i].y) / (polygon[j].y - polygon[i].y) + polygon[i].x));
if (intersect) {
inside = !inside;
}
}
return inside;
}
/**
@param corners Is an array of points with x,y attributes
@param startX X start coord for raycast
@param startY Y start coord for raycast
*/
static pointInPolygon(point, corners, start) {
start = start || new Vector2(0, 0);
var startX = start.x || 0;
var startY = start.y || 0;
//ensure that point(startX, startY) is outside the polygon consists of corners
var tMinX = 0,
tMinY = 0;
var tI = 0;
if (startX === undefined || startY === undefined) {
for (tI = 0; tI < corners.length; tI++) {
tMinX = Math.min(tMinX, corners[tI].x);
tMinY = Math.min(tMinX, corners[tI].y);
}
startX = tMinX - 10;
startY = tMinY - 10;
}
var tIntersects = 0;
for (tI = 0; tI < corners.length; tI++) {
var tFirstCorner = corners[tI],
tSecondCorner;
if (tI === corners.length - 1) {
tSecondCorner = corners[0];
} else {
tSecondCorner = corners[tI + 1];
}
if (Utils.lineLineIntersect(start, point, tFirstCorner.x, tFirstCorner.y, tSecondCorner.x, tSecondCorner.y)) {
tIntersects++;
}
}
// odd intersections means the point is in the polygon
return ((tIntersects % 2) === 1);
}
/** Checks if all corners of insideCorners are inside the polygon described by outsideCorners */
static polygonInsidePolygon(insideCorners, outsideCorners, start) {
start.x = start.x || 0;
start.y = start.y || 0;
for (var tI = 0; tI < insideCorners.length; tI++) {
if (!Utils.pointInPolygon(insideCorners[tI].x, insideCorners[tI].y, outsideCorners, start)) {
return false;
}
}
return true;
}
/** Checks if any corners of firstCorners is inside the polygon described by secondCorners */
static polygonOutsidePolygon(insideCorners, outsideCorners, start) {
start.x = start.x || 0;
start.y = start.y || 0;
for (var tI = 0; tI < insideCorners.length; tI++) {
if (Utils.pointInPolygon(insideCorners[tI].x, insideCorners[tI].y, outsideCorners, start)) {
return false;
}
}
return true;
}
// arrays
static forEach(array, action) {
for (var tI = 0; tI < array.length; tI++) {
action(array[tI]);
}
}
static forEachIndexed(array, action) {
for (var tI = 0; tI < array.length; tI++) {
action(tI, array[tI]);
}
}
static map(array, func) {
var tResult = [];
array.forEach((element) => {
tResult.push(func(element));
});
return tResult;
}
/** Remove elements in array if func(element) returns true */
static removeIf(array, func) {
var tResult = [];
array.forEach((element) => {
if (!func(element)) {
tResult.push(element);
}
});
return tResult;
}
/** Shift the items in an array by shift (positive integer) */
static cycle(arr, shift) {
var tReturn = arr.slice(0);
for (var tI = 0; tI < shift; tI++) {
var tmp = tReturn.shift();
tReturn.push(tmp);
}
return tReturn;
}
/** Returns in the unique elemnts in arr */
static unique(arr, hashFunc) {
var tResults = [];
var tMap = {};
for (var tI = 0; tI < arr.length; tI++) {
if (!tMap.hasOwnProperty(arr[tI])) {
tResults.push(arr[tI]);
tMap[hashFunc(arr[tI])] = true;
}
}
return tResults;
}
/** Remove value from array, if it is present */
static removeValue(array, value) {
for (var tI = array.length - 1; tI >= 0; tI--) {
if (array[tI] === value) {
array.splice(tI, 1);
return tI;
}
}
}
/** Checks if value is in array */
static hasValue(array, value) {
for (var tI = 0; tI < array.length; tI++) {
if (array[tI] === value) {
return true;
}
}
return false;
}
/** Subtracts the elements in subArray from array */
static subtract(array, subArray) {
return Utils.removeIf(array, function(el) {
return Utils.hasValue(subArray, el);
});
}
static point2Dto3D(point2D, elevation = 0) {
return new Vector3(point2D.x, elevation, point2D.y);
}
static point3Dto2D(point2D) {
return new Vector2(point2D.x, point2D.z);
}
static barycentricFromCartesian(triangle, point) {
//Vector ab
let ab = triangle[1].clone().sub(triangle[0]);
let ac = triangle[2].clone().sub(triangle[0]);
let ap = point.clone().sub(triangle[0]);
let dotAB = ab.dot(ab);
let dotAC = ac.dot(ac);
let dotABAC = ac.dot(ab);
let dotAPAB = ap.dot(ab);
let dotAPAC = ap.dot(ac);
//Area of triangle ABC
let areaABAC = (dotAB * dotAC) - (dotABAC * dotABAC);
let v = ((dotAC * dotAPAB) - (dotABAC * dotAPAC)) / areaABAC;
let w = ((dotAB * dotAPAC) - (dotABAC * dotAPAB)) / areaABAC;
let u = 1.0 - v - w;
return new Vector3(u, v, w);
}
static cartesianFromBarycenter(triangle, uvw) {
let a = triangle[0].clone();
let b = triangle[1].clone();
let c = triangle[2].clone();
let cartesian = a.multiplyScalar(uvw.x).add(b.multiplyScalar(uvw.y).add(c.multiplyScalar(uvw.z)));
return cartesian;
}
}
export class Region {
constructor(points) {
this.points = points || [];
this.length = points.length;
}
area() {
var area = 0,
i,
j,
point1,
point2;
for (i = 0, j = this.length - 1; i < this.length; j = i, i += 1) {
point1 = this.points[i];
point2 = this.points[j];
area += point1.x * point2.y;
area -= point1.y * point2.x;
}
area *= 0.5;
return area;
};
centroid() {
var x = 0,
y = 0,
i,
j,
f,
point1,
point2;
for (i = 0, j = this.length - 1; i < this.length; j = i, i += 1) {
point1 = this.points[i];
point2 = this.points[j];
f = point1.x * point2.y - point2.x * point1.y;
x += (point1.x + point2.x) * f;
y += (point1.y + point2.y) * f;
}
f = this.area() * 6;
return new Vector2(x / f, y / f);
};
}

28
src/blueprint/scripts/core/version.ts

@ -0,0 +1,28 @@
export class Version {
static isVersionHigherThan(version, checkVersion) {
if (version != undefined) {
checkVersion = checkVersion.replace(/[^\d.-]/g, '').split('.');
var givenVersion = version.replace(/[^\d.-]/g, '').split('.');
var flag = true;
if (checkVersion.length != givenVersion.length) {
return false;
}
for (var i = 0; i < checkVersion.length; i++) {
var a = parseInt(checkVersion[i]);
var b = parseInt(givenVersion[i]);
flag && (a >= b);
}
return flag;
}
return false;
}
static getInformalVersion() {
return '2.0.1a';
}
static getTechnicalVersion() {
return '2.0.1a';
}
}

90
src/blueprint/scripts/helpers/ConfigurationHelper.ts

@ -0,0 +1,90 @@
import { Configuration, gridSpacing, snapTolerance, boundsY, boundsX, dragOnlyY, dragOnlyX, directionalDrag, snapToGrid } from '../core/configuration';
export class ConfigurationHelper {
__snapToGrid: boolean;
__directionalDrag: boolean;
__dragOnlyX: boolean;
__dragOnlyY: boolean;
__boundsX: number;
__boundsY: number;
__snapTolerance: number;
__gridSpacing: number;
constructor() {
this.__snapToGrid = Configuration.getBooleanValue(snapToGrid);
this.__directionalDrag = Configuration.getBooleanValue(directionalDrag);
this.__dragOnlyX = Configuration.getBooleanValue(dragOnlyX);
this.__dragOnlyY = Configuration.getBooleanValue(dragOnlyY);
this.__boundsX = Configuration.getNumericValue(boundsX);
this.__boundsY = Configuration.getNumericValue(boundsY);
this.__snapTolerance = Configuration.getNumericValue(snapTolerance);
this.__gridSpacing = Configuration.getNumericValue(gridSpacing);
}
get snapToGrid() {
return this.__snapToGrid;
}
set snapToGrid(flag) {
this.__snapToGrid = flag;
Configuration.setValue(snapToGrid, flag);
}
get directionalDrag() {
return this.__directionalDrag;
}
set directionalDrag(flag) {
this.__directionalDrag = flag;
Configuration.setValue(directionalDrag, flag);
}
get dragOnlyX() {
return this.__dragOnlyX;
}
set dragOnlyX(flag) {
this.__dragOnlyX = flag;
Configuration.setValue(dragOnlyX, flag);
}
get dragOnlyY() {
return this.__dragOnlyY;
}
set dragOnlyY(flag) {
this.__dragOnlyY = flag;
Configuration.setValue(dragOnlyY, flag);
}
get boundsX() {
return this.__boundsX;
}
set boundsX(value) {
this.__boundsX = value;
Configuration.setValue(boundsX, value);
}
get boundsY() {
return this.__boundsY;
}
set boundsY(value) {
this.__boundsY = value;
Configuration.setValue(boundsY, value);
}
get snapTolerance() {
return this.__snapTolerance;
}
set snapTolerance(value) {
this.__snapTolerance = value;
Configuration.setValue(snapTolerance, value);
}
get gridSpacing() {
return this.__gridSpacing;
}
set gridSpacing(value) {
this.__gridSpacing = value;
Configuration.setValue(gridSpacing, value);
}
}

16
src/blueprint/scripts/helpers/DeviceInfo.ts

@ -0,0 +1,16 @@
export class DeviceInfo {
constructor() {
}
static isTouchDevice() {
try {
document.createEvent('TouchEvent');
return true;
} catch (e) {
return false;
}
}
}
export const IS_TOUCH_DEVICE = DeviceInfo.isTouchDevice();

141
src/blueprint/scripts/helpers/FloorplannerHelper.ts

@ -0,0 +1,141 @@
import { Dimensioning } from "../core/dimensioning";
import { EVENT_CORNER_2D_CLICKED, EVENT_NOTHING_2D_SELECTED, EVENT_WALL_2D_CLICKED, EVENT_ROOM_2D_CLICKED } from "../core/EventSystem";
export class FloorPlannerHelper {
__floorplan;
__floorplanner;
__wallThickness;
__cornerElevation;
__roomName: string;
/**
* Store a reference to the model entities
*/
__selectedWall;
__selectedCorner;
__selectedRoom;
/**
* Store a reference to the viewer3d visual entities
*/
__selectedWallEntity = null;
__selectedCornerEntity = null;
__selectedRoomEntity = null;
__nothingSelectedEvent;
__cornerSelectedEvent;
__wallSelectedEvent;
__roomSelectedEvent;
constructor(floorplan, floorplanner) {
this.__floorplan = floorplan;
this.__floorplanner = floorplanner;
this.__wallThickness = Dimensioning.cmToMeasureRaw(20);
this.__cornerElevation = Dimensioning.cmToMeasureRaw(250);
this.__roomName = 'A New Room';
/**
* Store a reference to the model entities
*/
this.__selectedWall = null;
this.__selectedCorner = null;
this.__selectedRoom = null;
/**
* Store a reference to the viewer3d visual entities
*/
this.__selectedWallEntity = null;
this.__selectedCornerEntity = null;
this.__selectedRoomEntity = null;
this.__nothingSelectedEvent = this.__resetSelections.bind(this);
this.__cornerSelectedEvent = this.__cornerSelected.bind(this);
this.__wallSelectedEvent = this.__wallSelected.bind(this);
this.__roomSelectedEvent = this.__roomSelected.bind(this);
this.__floorplanner.addFloorplanListener(EVENT_NOTHING_2D_SELECTED, this.__nothingSelectedEvent);
this.__floorplanner.addFloorplanListener(EVENT_CORNER_2D_CLICKED, this.__cornerSelectedEvent);
this.__floorplanner.addFloorplanListener(EVENT_WALL_2D_CLICKED, this.__wallSelectedEvent);
this.__floorplanner.addFloorplanListener(EVENT_ROOM_2D_CLICKED, this.__roomSelectedEvent);
}
__resetSelections() {
this.__selectedCorner = null;
this.__selectedWall = null;
this.__selectedRoom = null;
this.__selectedCornerEntity = null;
this.__selectedWallEntity = null;
this.__selectedRoomEntity = null;
}
__cornerSelected(evt) {
this.__resetSelections();
this.__selectedCorner = evt.item;
this.__selectedCornerEntity = evt.entity;
this.__cornerElevation = Dimensioning.cmToMeasureRaw(this.__selectedCorner.elevation);
}
__wallSelected(evt) {
this.__resetSelections();
this.__selectedWall = evt.item;
this.__selectedWallEntity = evt.entity;
this.__wallThickness = Dimensioning.cmToMeasureRaw(evt.item.thickness);
}
__roomSelected(evt) {
this.__resetSelections();
this.__selectedRoom = evt.item;
this.__selectedRoomEntity = evt.entity;
this.__roomName = evt.item.name;
}
__nothingSelected() {
this.__resetSelections();
}
deleteCurrentItem() {
if (this.__selectedWall) {
this.__selectedWall.remove();
this.__resetSelections();
}
if (this.__selectedCorner) {
this.__selectedCorner.remove();
this.__resetSelections();
}
}
set wallThickness(value) {
if (this.__selectedWall) {
let cms = Dimensioning.cmFromMeasureRaw(value);
this.__selectedWall.thickness = cms;
this.__wallThickness = value;
}
}
get wallThickness() {
return Dimensioning.cmToMeasureRaw(this.__wallThickness);
}
set cornerElevation(value) {
if (this.__selectedCorner) {
let cms = Dimensioning.cmFromMeasureRaw(value);
this.__selectedCorner.elevation = cms;
this.__cornerElevation = value;
}
}
get cornerElevation() {
return Dimensioning.cmToMeasureRaw(this.__cornerElevation);
}
set roomName(value) {
if (this.__selectedRoom) {
this.__selectedRoom.name = value;
this.__roomName = value;
}
}
get roomName() {
return this.__roomName;
}
}

221
src/blueprint/scripts/helpers/RoomplannerHelper.ts

@ -0,0 +1,221 @@
import { TEXTURE_PROPERTY_COLOR } from "../core/constants";
import { Dimensioning } from "../core/dimensioning";
import { EVENT_CORNER_2D_CLICKED, EVENT_NOTHING_2D_SELECTED, EVENT_WALL_2D_CLICKED, EVENT_ROOM_2D_CLICKED, EVENT_NO_ITEM_SELECTED, EVENT_ITEM_SELECTED, EVENT_WALL_CLICKED, EVENT_ROOM_CLICKED } from "../core/EventSystem";
import { InWallFloorItem } from "../items/in_wall_floor_item";
export class RoomPlannerHelper {
__model;
__floorplan;
__roomplanner;
__wallThickness;
__cornerElevation;
__roomName;
__selectedEdge = null;
__selectedEdgeNormal = null;
__selectedEdgePoint = null;
__selectedItem = null;
__selectedRoom = null;
__wallTexturePack = null;
__roomTexturePack = null;
__roomWallsTexturePack = null;
__nothingSelectedEvent;
__itemSelectedEvent;
__wallSelectedEvent;
__roomSelectedEvent;
__selectedCorner;
constructor(model, floorplan, roomplanner) {
this.__model = model;
this.__floorplan = floorplan;
this.__roomplanner = roomplanner;
this.__wallThickness = Dimensioning.cmToMeasureRaw(20);
this.__cornerElevation = Dimensioning.cmToMeasureRaw(250);
this.__roomName = 'A New Room';
this.__selectedEdge = null;
this.__selectedEdgeNormal = null;
this.__selectedEdgePoint = null;
this.__selectedItem = null;
this.__selectedRoom = null;
this.__wallTexturePack = null;
this.__roomTexturePack = null;
this.__roomWallsTexturePack = null;
this.__nothingSelectedEvent = this.__nothingSelected.bind(this);
this.__itemSelectedEvent = this.__itemSelected.bind(this);
this.__wallSelectedEvent = this.__wallSelected.bind(this);
this.__roomSelectedEvent = this.__roomSelected.bind(this);
this.__roomplanner.addRoomplanListener(EVENT_NO_ITEM_SELECTED, this.__nothingSelectedEvent);
this.__roomplanner.addRoomplanListener(EVENT_ITEM_SELECTED, this.__itemSelectedEvent);
this.__roomplanner.addRoomplanListener(EVENT_WALL_CLICKED, this.__wallSelectedEvent);
this.__roomplanner.addRoomplanListener(EVENT_ROOM_CLICKED, this.__roomSelectedEvent);
}
__itemSelected(evt) {
this.__selectedItem = evt.item;
}
__wallSelected(evt) {
this.__selectedEdge = evt.item;
this.__selectedEdgeNormal = evt.normal;
this.__selectedEdgePoint = evt.point;
this.__wallThickness = Dimensioning.cmToMeasureRaw(evt.item.thickness);
}
__roomSelected(evt) {
this.__selectedRoom = evt.item;
this.__roomName = evt.item.name;
}
__nothingSelected() {
// this.__selectedEdge = null;
// this.__selectedRoom = null;
// this.__selectedItem = null;
}
addParametricDoorToCurrentWall(doorType) {
if (!this.__selectedEdge) {
return;
}
let itemMetaData = {
itemName: "Parametric Door",
isParametric: true,
baseParametricType: "DOOR",
subParametricData: {
type: doorType,
frameColor: "#E7E7E7",
doorColor: "#E7E7E7",
doorHandleColor: '#F0F0F0',
glassColor: '#87CEEB',
frameWidth: 100,
frameHeight: 200,
frameSize: 5,
frameThickness: 20,
doorRatio: 0.5,
openDirection: "RIGHT",
handleType: "HANDLE_01"
},
itemType: 7,
position: [
0,
0,
0
],
rotation: [
0,
0,
0
],
scale: [
1,
1,
1
],
size: [
100,
200,
20
],
fixed: false,
resizable: false,
wall: this.__selectedEdge.id,
};
let item = new InWallFloorItem(itemMetaData, this.__model);
this.__model.addItem(item);
// console.log(this.__selectedEdgePoint, this.__selectedEdgeNormal);
item.snapToWall(this.__selectedEdgePoint, this.__selectedEdge.wall, this.__selectedEdge);
}
set wallThickness(value) {
if (this.__selectedEdge) {
let cms = Dimensioning.cmFromMeasureRaw(value);
this.__selectedEdge.thickness = cms;
this.__wallThickness = value;
}
}
get wallThickness() {
return Dimensioning.cmToMeasureRaw(this.__wallThickness);
}
set cornerElevation(value) {
if (this.__selectedCorner) {
let cms = Dimensioning.cmFromMeasureRaw(value);
this.__selectedCorner.elevation = cms;
this.__cornerElevation = value;
}
}
get cornerElevation() {
return Dimensioning.cmToMeasureRaw(this.__cornerElevation);
}
set roomName(value) {
if (this.__selectedRoom) {
this.__selectedRoom.name = value;
this.__roomName = value;
}
}
get roomName() {
return this.__roomName;
}
get wallTexturePack() {
return this.__wallTexturePack;
}
set wallTexturePack(tpack) {
this.__wallTexturePack = tpack;
if (this.__selectedEdge) {
this.__selectedEdge.setTextureMaps(tpack);
}
}
get roomTexturePack() {
return this.__roomTexturePack;
}
set roomTexturePack(tpack) {
this.__roomTexturePack = tpack;
if (this.__selectedRoom) {
this.__selectedRoom.setTextureMaps(tpack);
}
}
get roomWallsTexturePack() {
return this.__roomWallsTexturePack;
}
set roomWallsTexturePack(tpack) {
this.__roomTexturePack = tpack;
if (this.__selectedRoom) {
this.__selectedRoom.setRoomWallsTextureMaps(tpack);
}
}
setWallColor(color) {
if (this.__selectedEdge) {
this.__selectedEdge.setTextureMapAttribute(TEXTURE_PROPERTY_COLOR, color);
}
}
setRoomWallsTextureColor(color) {
if (this.__selectedRoom) {
this.__selectedRoom.setRoomWallsTextureMapsAttribute(TEXTURE_PROPERTY_COLOR, color);
}
}
setRoomFloorColor(color) {
if (this.__selectedRoom) {
this.__selectedRoom.setTextureMapAttribute(TEXTURE_PROPERTY_COLOR, color);
}
}
}

20
src/blueprint/scripts/items/factory.js

@ -0,0 +1,20 @@
import {Item} from './item.js';
import {FloorItem} from './floor_item.js';
import {WallItem} from './wall_item.js';
import {InWallItem} from './in_wall_item.js';
import {InWallFloorItem} from './in_wall_floor_item.js';
import {OnFloorItem} from './on_floor_item.js';
import {WallFloorItem} from './wall_floor_item.js';
import {RoofItem} from './roof_item.js';
export const item_types = {1: FloorItem, 2: WallItem, 3: InWallItem, 7: InWallFloorItem, 8: OnFloorItem, 9: WallFloorItem, 0: Item, 4: RoofItem};
/** Factory class to create items. */
export class Factory
{
/** Gets the class for the specified item. */
static getClass(itemType)
{
return item_types[itemType];
}
}

32
src/blueprint/scripts/items/floor_item.js

@ -0,0 +1,32 @@
import { Item, UP_VECTOR } from './item.js';
import { Vector2, Vector3 } from 'three';
import { Utils } from '../core/utils.js';
/**
* A Floor Item is an entity to be placed related to a floor.
*/
export class FloorItem extends Item {
constructor(model, metadata, id) {
super(model, metadata, id);
this._freePosition = false;
this.__customIntersectionPlanes = this.__model.floorplan.floorPlanesForIntersection;
}
snapToPoint(point, normal, intersectingPlane, toWall, toFloor, toRoof) {
let normal2d = new Vector2(normal.x, normal.z);
let angle = Utils.angle(UP_VECTOR, normal2d);
this.rotation = new Vector3(0, angle, 0);
point.y = this.halfSize.y + 5;
this.position = point;
}
// /** */
// placeInRoom() {
// if (!this.position_set) {
// var center = this.__model.floorplan.getCenter();
// this.position.x = center.x;
// this.position.z = center.z;
// this.position.y = 0.5 * (this.geometry.boundingBox.max.y - this.geometry.boundingBox.min.y);
// }
// }
}

39
src/blueprint/scripts/items/in_wall_floor_item.js

@ -0,0 +1,39 @@
import { InWallItem } from './in_wall_item.js';
import { Vector2, Vector3, Matrix4 } from 'three';
import { UP_VECTOR } from './item.js';
import { Utils } from '../core/utils.js';
/** */
export class InWallFloorItem extends InWallItem {
constructor(model, metadata, id) {
super(model, metadata, id);
this.__customIntersectionPlanes = this.__model.floorplan.wallPlanesForIntersection;
}
snapToPoint(point, normal, intersectingPlane, toWall, toFloor, toRoof) {
this.snapToWall(point, intersectingPlane.wall, intersectingPlane.edge);
}
snapToWall(point, wall, wallEdge) {
point = this.__fitToWallBounds(point, wallEdge);
let normal = wallEdge.normal;
let normal2d = new Vector2(normal.x, normal.z);
let angle = Utils.angle(UP_VECTOR, normal2d);
this.rotation = new Vector3(0, angle, 0);
point.y = this.halfSize.y + 5;
this.position = point;
this.__currentWallSnapPoint = point.clone();
this.__currentWallNormal = normal.clone();
this.__addToAWall(wall, wallEdge);
}
__parametricGeometryUpdate(evt, updateForWall = true) {
super.__parametricGeometryUpdate(evt, false);
if (this.__currentWall && updateForWall) {
let currentPosition = this.position.clone();
currentPosition.y = this.halfSize.y + 5;
this.position = currentPosition;
this.__currentWall.addItem(this);
}
}
}

26
src/blueprint/scripts/items/in_wall_item.js

@ -0,0 +1,26 @@
import { WallItem } from './wall_item.js';
import { Vector2, Vector3 } from 'three';
import { Utils } from '../core/utils.js';
import { UP_VECTOR } from './item.js';
/** */
export class InWallItem extends WallItem {
constructor(model, metadata, id) {
super(model, metadata, id);
this.__customIntersectionPlanes = this.__model.floorplan.wallPlanesForIntersection;
}
snapToPoint(point, normal, intersectingPlane, toWall, toFloor, toRoof) {
this.snapToWall(point, intersectingPlane.wall, intersectingPlane.edge);
}
snapToWall(point, wall, wallEdge) {
point = this.__fitToWallBounds(point, wallEdge);
let normal = wallEdge.normal;
let normal2d = new Vector2(normal.x, normal.z);
let angle = Utils.angle(UP_VECTOR, normal2d);
this.rotation = new Vector3(0, angle, 0);
this.position = point;
this.__currentWallSnapPoint = point.clone();
this.__addToAWall(wall, wallEdge);
}
}

400
src/blueprint/scripts/items/item.js

@ -0,0 +1,400 @@
import { EventDispatcher, Vector3, Vector2 } from 'three';
import { EVENT_UPDATED, EVENT_PARAMETRIC_GEOMETRY_UPATED, EVENT_MOVED, EVENT_DELETED } from '../core/events';
import { Utils } from '../core/utils';
import { BASE_PARAMETRIC_TYPES, ParametricFactory } from '../parametrics/ParametricFactory';
export const UP_VECTOR = new Vector3(0, 1, 0);
/**
* An Item is an abstract entity for all things placed in the scene, e.g. at
* walls or on the floor.
*/
export class Item extends EventDispatcher {
/**
* Constructs an item. This is a pure data representation of a room item.
* Because floorplanner is pure MVC or MVP it is the responsibility of the respective viewer
* to create the physical entity based on the item data
*
* @param model
* TODO
* @param metadata
* TODO
* @param id
* TODO
*/
constructor(metadata, model, id) {
super();
/**
* @property {String} id The id of this corner. Autogenerated the first time
* @type {String}
**/
this.__id = id || Utils.guide();
this.__metadata = metadata;
this.__model = model;
this.__position2d = new Vector2();
this.__position = new Vector3();
this.__rotation = new Vector3();
this.__scale = new Vector3(1, 1, 1);
this.__size = new Vector3(1, 1, 1);
this.__halfSize = new Vector3(1, 1, 1);
this.__customIntersectionPlanes = [];
/** */
this.__hover = false; //This is part of application logic only
/** */
this.__selected = false; //This is part of application logic only
this.__freePosition = true; //This is part of application logic only
this.__boundToFloor = false; //This is part of application logic only
this.__allowRotate = true; //This is part of application logic only
this.__fixed = false; //This is part of application logic and also Metadata
this.__resizable = false; //This is part of application logic and also Metadata
this.__frontVisible = false;
this.__backVisible = false;
this.__visible = true;
this.__offlineUpdate = false;
this.__isParametric = false;
this.__baseParametricType = BASE_PARAMETRIC_TYPES.DOOR;
this.__subParametricType = 1;
this.__parametricClass = null;
this.__currentWall = null;
this.__currentFloor = null;
this.__currentWallNormal = null;
this.__currentWallSnapPoint = null;
this.__isWallDependent = false;
this.__followWallEvent = this.__followWall.bind(this);
this.__edgeDeletedEvent = this.__edgeDeleted.bind(this);
this.__parametricGeometryUpdateEvent = this.__parametricGeometryUpdate.bind(this);
this.castShadow = false;
this.receiveShadow = false;
this.__initializeMetaData();
}
__initializeMetaData() {
this.__fixed = (this.__metadata.fixed) ? this.__metadata.fixed : true;
this.__resizable = (this.__metadata.resizable) ? this.__metadata.resizable : true;
if (this.__metadata.position.length) {
this.__position = new Vector3().fromArray(this.__metadata.position).clone();
}
if (this.__metadata.rotation.length) {
this.__rotation = new Vector3().fromArray(this.__metadata.rotation).clone();
}
if (this.__metadata.scale.length) {
this.__scale = new Vector3().fromArray(this.__metadata.scale).clone();
}
if (this.__metadata.size.length) {
this.__size = new Vector3().fromArray(this.__metadata.size).clone();
this.__halfSize = this.__size.clone().multiplyScalar(0.5);
}
if (this.__metadata.isParametric) {
this.__isParametric = this.__metadata.isParametric;
switch (this.__metadata.baseParametricType) {
case BASE_PARAMETRIC_TYPES.DOOR.description:
this.__baseParametricType = BASE_PARAMETRIC_TYPES.DOOR;
break;
case BASE_PARAMETRIC_TYPES.WINDOW.description:
this.__baseParametricType = BASE_PARAMETRIC_TYPES.WINDOW;
break;
case BASE_PARAMETRIC_TYPES.CABINET.description:
this.__baseParametricType = BASE_PARAMETRIC_TYPES.CABINET;
break;
case BASE_PARAMETRIC_TYPES.SHELVES.description:
this.__baseParametricType = BASE_PARAMETRIC_TYPES.SHELVES;
break;
}
this.__subParametricData = this.__metadata.subParametricData;
let parametricClass = ParametricFactory.getParametricClass(this.__baseParametricType.description);
this.__parametricClass = new(parametricClass.getClass(this.__subParametricData.type))(this.__subParametricData);
this.__parametricClass.addEventListener(EVENT_PARAMETRIC_GEOMETRY_UPATED, this.__parametricGeometryUpdateEvent);
} else {
this.__isParametric = false;
}
if (this.__metadata.wall) {
let walls = this.__model.floorplan.walls;
for (let i = 0; i < walls.length; i++) {
let wall = walls[i];
if (wall.id === this.__metadata.wall) {
let wallEdge = (this.__metadata.wallSide === 'front') ? wall.frontEdge : wall.backEdge;
let wallSurfacePoint = this.__metadata.wallSurfacePoint;
this.__currentWallSnapPoint = new Vector3(wallSurfacePoint[0], wallSurfacePoint[1], wallSurfacePoint[2]);
this.__addToAWall(wall, wallEdge);
break;
}
}
}
}
__parametricGeometryUpdate(evt, updateForWall = true) {
let box = this.__parametricClass.geometry.boundingBox;
this.__size = box.getSize(new Vector3());
this.__halfSize = this.__size.clone().multiplyScalar(0.5);
if (this.__currentWall && updateForWall) {
let point = Utils.cartesianFromBarycenter(this.__currentWallEdge.vertices, this.__barycentricLocation);
this.snapToWall(point, this.__currentWall, this.__currentWallEdge);
// this.position = this.__position;
// this.__currentWall.addItem(this);
}
}
__edgeDeleted(evt) {
if (this.__currentWall) {
let wallEdge = (this.__metadata.wallSide === 'front') ? this.__currentWall.frontEdge : this.__currentWall.backEdge;
this.__currentWallEdge = null;
let point = Utils.cartesianFromBarycenter(wallEdge.vertices, this.__barycentricLocation);
this.snapToWall(point, this.__currentWall, wallEdge);
}
}
__followWall(evt) {
if (this.__isWallDependent && this.__currentWall && !this.__offlineUpdate) {
let point = Utils.cartesianFromBarycenter(this.__currentWallEdge.vertices, this.__barycentricLocation);
this.snapToWall(point, this.__currentWall, this.__currentWallEdge);
}
}
__addToAWall(toWall, toWallEdge) {
if (toWall === undefined || !toWall || toWall === 'undefined') {
return;
}
if (this.__currentWall && this.__currentWall !== toWall) {
this.__currentWall.removeEventListener(EVENT_MOVED, this.__followWallEvent);
this.__currentWallEdge.removeEventListener(EVENT_DELETED, this.__edgeDeletedEvent);
this.__currentWall.removeItem(this);
}
let barycentricUVW = Utils.barycentricFromCartesian(toWallEdge.vertices, this.__currentWallSnapPoint);
this.__currentWall = toWall;
this.__currentWallEdge = toWallEdge;
this.__barycentricLocation = barycentricUVW.clone();
this.__metadata.wall = this.__currentWall.id;
this.__metadata.wallSide = (toWallEdge.front) ? 'front' : 'back';
this.__metadata.wallSurfacePoint = [this.__currentWallSnapPoint.x, this.__currentWallSnapPoint.y, this.__currentWallSnapPoint.z];
this.__offlineUpdate = true; //Really important as it will lead to a lot of recursion
this.__currentWall.addItem(this); //This causes wall to dispatch event_moved triggering followWall, which will trigger this method again
this.__offlineUpdate = false; //Really important as it will lead to a lot of recursion
if (!this.__currentWall.hasEventListener(EVENT_MOVED, this.__followWallEvent)) {
this.__currentWall.addEventListener(EVENT_MOVED, this.__followWallEvent);
this.__currentWallEdge.addEventListener(EVENT_DELETED, this.__edgeDeletedEvent);
}
}
/** */
__moveToPosition() {}
__getMetaData() {
return {
id: this.id,
itemName: this.metadata.itemName,
itemType: this.metadata.itemType,
modelURL: this.metadata.modelUrl,
position: this.position.toArray(),
rotation: this.rotation.toArray(),
scale: this.scale.toArray(),
size: this.size.toArray(),
fixed: this.__fixed,
resizable: this.__resizable
};
}
__metaDataUpdate(propertyname) {
this.dispatchEvent({ type: EVENT_UPDATED, property: propertyname });
}
updateMetadataExplicit() {
this.__metadata = this.__getMetaData();
}
snapToPoint(point, normal, intersectingPlane, toWall, toFloor, toRoof) {
this.position = point;
}
snapToWall(point, wall, wallEdge) {}
newWallEdge() {
let wallEdge = (this.__metadata.wallSide === 'front') ? this.__currentWall.frontEdge : this.__currentWall.backEdge;
this.__currentWallEdge = null;
this.__currentWallEdge = wallEdge;
}
dispose() {
if (this.isParametric && this.__parametricClass) {
this.__parametricClass.removeEventListener(EVENT_PARAMETRIC_GEOMETRY_UPATED, this.__parametricGeometryUpdateEvent);
}
if (this.__currentWall) {
this.__currentWall.removeEventListener(EVENT_MOVED, this.__followWallEvent);
}
if (this.__currentWallEdge) {
this.__currentWallEdge.removeEventListener(EVENT_DELETED, this.__edgeDeletedEvent);
}
}
get id() {
return this.__id;
}
get metadata() {
if (this.isParametric) {
this.__metadata.subParametricData = this.__parametricClass.metadata;
}
return this.__metadata;
}
set metadata(mdata) {
this.__metadata = mdata;
this.__applyMetaData();
}
get position2d() {
return this.__position2d;
}
get position() {
return this.__position;
}
set position(p) {
this.__position2d.x = p.x;
this.__position2d.y = p.z;
this.__position.copy(p);
this.__metadata.position = this.__position.toArray();
this.__moveToPosition();
this.__metaDataUpdate('position');
}
get rotation() {
return this.__rotation;
}
set rotation(r) {
let old = this.__rotation.clone();
let current = r.clone();
if (old.sub(current).length() < 1e-4) {
return;
}
this.__rotation.copy(r);
this.__metadata.rotation = this.__rotation.toArray();
this.__metaDataUpdate('rotation');
}
get scale() {
return this.__scale;
}
set scale(s) {
this.__scale.copy(s);
this.__metadata.scale = this.__scale.toArray();
this.__metaDataUpdate('scale');
}
/**
* This is a read-only property. This can be changed only internally with private and protected acces
*/
get size() {
return this.__size.clone();
}
get modelURL() {
return this.__metadata.modelURL;
}
set modelURL(value) {
this.__metadata.modelURL = value;
this.__metaDataUpdate('modelURL');
}
get fixed() {
return this.__fixed;
}
set fixed(flag) {
this.__fixed = flag;
this.__metaDataUpdate('fixed');
}
get frontVisible() {
return this.__frontVisible;
}
set frontVisible(flag) {
this.__frontVisible = flag;
}
get backVisible() {
return this.__backVisible;
}
set backVisible(flag) {
this.__backVisible = flag;
}
get visible() {
return this.__visible;
}
set visible(flag) {
this.__visible = flag;
// this.frontVisible = false;
// this.backVisible = false;
this.__metaDataUpdate('visible');
}
get isParametric() {
return this.__isParametric;
}
get baseParametricType() {
return this.__baseParametricType;
}
get subParametricData() {
return this.__subParametricData;
}
get parametricClass() {
return this.__parametricClass;
}
get resizable() {
return this.__resizable;
}
get itemName() {
return this.__metadata.itemName;
}
get itemType() {
return this.__metadata.itemType;
}
get halfSize() {
return this.__halfSize.clone();
}
get intersectionPlanes() {
return this.__customIntersectionPlanes;
}
get isWallDependent() {
return this.__isWallDependent;
}
get offlineUpdate() {
return this.__offlineUpdate;
}
get wallSide() {
return this.__metadata.wallSide;
}
}

11
src/blueprint/scripts/items/on_floor_item.js

@ -0,0 +1,11 @@
import { FloorItem } from './floor_item.js';
import { Item } from './item.js';
/** */
export class OnFloorItem extends Item {
constructor(model, metadata, id) {
super(model, metadata, id);
this.receiveShadow = true;
this.__customIntersectionPlanes = this.__model.floorplan.floorPlanesForIntersection;
}
}

16
src/blueprint/scripts/items/roof_item.js

@ -0,0 +1,16 @@
import { Item } from './item.js';
import { Matrix4, Triangle, Plane, Vector3 } from 'three';
/**
* A Floor Item is an entity to be placed related to a floor.
*/
export class RoofItem extends Item {
constructor(model, metadata, id) {
super(model, metadata, id);
this.__customIntersectionPlanes = this.__model.floorplan.roofPlanesForIntersection;
}
snapToPoint(point, normal, intersectingPlane, toWall, toFloor, toRoof) {
point.y -= this.halfSize.y + 5;
this.position = point;
}
}

43
src/blueprint/scripts/items/wall_floor_item.js

@ -0,0 +1,43 @@
import { WallItem } from './wall_item.js';
import { Vector2, Vector3 } from 'three';
import { Utils } from '../core/utils.js';
import { UP_VECTOR } from './item.js';
/** */
export class WallFloorItem extends WallItem {
constructor(model, metadata, id) {
super(model, metadata, id);
this.__boundToFloor = true;
this.__customIntersectionPlanes = this.__model.floorplan.wallPlanesForIntersection;
}
snapToPoint(point, normal, intersectingPlane, toWall, toFloor, toRoof) {
this.snapToWall(point, intersectingPlane.wall, intersectingPlane.edge);
}
snapToWall(point, wall, wallEdge) {
point = this.__fitToWallBounds(point, wallEdge);
let normal = wallEdge.normal;
let normal2d = new Vector2(normal.x, normal.z);
let angle = Utils.angle(UP_VECTOR, normal2d);
this.__currentWallNormal = normal.clone();
this.__currentWallSnapPoint = point.clone();
point = point.clone().add(normal.clone().multiplyScalar(this.halfSize.z + (wall.thickness * 0.25)));
point.y = this.halfSize.y + 5;
this.rotation = new Vector3(0, angle, 0);
this.position = point;
this.__addToAWall(wall, wallEdge);
}
__parametricGeometryUpdate(evt, updateForWall = true) {
super.__parametricGeometryUpdate(evt, false);
if (this.__currentWall && updateForWall) {
let point = this.__currentWallSnapPoint.clone();
point = point.clone().add(this.__currentWallNormal.clone().multiplyScalar(this.halfSize.z + (this.__currentWall.thickness * 0.25)));
point.y = this.halfSize.y + 5;
this.position = point;
this.__currentWall.addItem(this);
}
}
}

68
src/blueprint/scripts/items/wall_item.js

@ -0,0 +1,68 @@
import { Vector2, Vector3 } from 'three';
import { Utils } from '../core/utils.js';
import { Item, UP_VECTOR } from './item.js';
/**
* A Wall Item is an entity to be placed related to a wall.
*/
export class WallItem extends Item {
constructor(model, metadata, id) {
super(model, metadata, id);
this.__isWallDependent = true;
this.__boundToFloor = false;
this.__allowRotate = false;
this.__freePosition = false;
this.__customIntersectionPlanes = this.__model.floorplan.wallPlanesForIntersection;
}
__fitToWallBounds(point, wallEdge) {
let point2d = new Vector2(point.x, point.z);
let wallEdgeVector = wallEdge.interiorEnd().clone().sub(wallEdge.interiorStart());
let sizeX = this.__halfSize.x + 5;
let sizeVector = wallEdgeVector.clone().normalize().multiplyScalar(sizeX);
let positionMinusSize = point2d.clone().sub(sizeVector);
let positionPlusSize = point2d.clone().add(sizeVector);
let startToPlusSizeVector = positionPlusSize.sub(wallEdge.interiorStart());
let endToMinusSizeVector = positionMinusSize.sub(wallEdge.interiorEnd());
if (startToPlusSizeVector.length() > wallEdgeVector.length()) {
let p = wallEdge.interiorEnd().clone().sub(sizeVector);
return new Vector3(p.x, point.y, p.y);
}
if (endToMinusSizeVector.length() > wallEdgeVector.length()) {
let p = wallEdge.interiorStart().clone().add(sizeVector);
return new Vector3(p.x, point.y, p.y);
}
return point;
}
snapToPoint(point, normal, intersectingPlane, toWall, toFloor, toRoof) {
this.snapToWall(point, intersectingPlane.wall, intersectingPlane.edge);
}
snapToWall(point, wall, wallEdge) {
super.snapToWall(point, wall, wallEdge);
point = this.__fitToWallBounds(point, wallEdge);
let normal = wallEdge.normal;
let normal2d = new Vector2(normal.x, normal.z);
let angle = Utils.angle(UP_VECTOR, normal2d);
this.__currentWallNormal = normal.clone();
this.__currentWallSnapPoint = point.clone();
point = point.clone().add(normal.clone().multiplyScalar(this.halfSize.z + (wall.thickness * 0.25)));
this.position = point;
this.rotation = new Vector3(0, angle, 0);
this.__addToAWall(wall, wallEdge);
}
__parametricGeometryUpdate(evt, updateForWall = true) {
super.__parametricGeometryUpdate(evt, false);
if (this.__currentWall && updateForWall) {
let point = this.__currentWallSnapPoint.clone();
point = point.clone().add(this.__currentWallNormal.clone().multiplyScalar(this.halfSize.z + (this.__currentWall.thickness * 0.25)));
this.position = point;
this.__currentWall.addItem(this);
}
}
}

7
src/blueprint/scripts/materials/FloorMaterial3D.js

@ -0,0 +1,7 @@
import { Material3D } from "./Material3D";
export class FloorMaterial3D extends Material3D {
constructor(parameters, textureMapPack, scene) {
super(parameters, textureMapPack, scene, false);
}
}

241
src/blueprint/scripts/materials/Material3D.js

@ -0,0 +1,241 @@
import { MeshStandardMaterial, TextureLoader, RepeatWrapping, Color, Vector2, sRGBEncoding, CubeReflectionMapping } from 'three';
import { TEXTURE_DEFAULT_REPEAT } from '../core/constants';
export class Material3D extends MeshStandardMaterial {
constructor(parameters, textureMapPack, scene, reflectsScene = false) {
super(parameters);
// console.log('BLENDING :: ',this.blending);
this.__scene = scene;
this.__reflectsScene = reflectsScene;
this.__mirrorCamera = null;
// this.roughness = (!textureMapPack.reflective) ? 0.5 : textureMapPack.reflective;
this.__repeat = (!textureMapPack.repeat) ? TEXTURE_DEFAULT_REPEAT : textureMapPack.repeat;
this.__repeatX = null;
this.__repeatY = null;
if (this.__reflectsScene) {
this.__mirrorCamera = this.__scene.environmentCamera;
this.envMap = this.__mirrorCamera.renderTarget.texture;
this.envMap.mapping = CubeReflectionMapping;
}
this.__textureMapPack = textureMapPack;
this.__uRatio = 1.0;
this.__vRatio = 1.0;
this.__dimensions = new Vector2();
this.__repeatPerCentimeter = 1.0 / this.__repeat; //Repeat for every 'x' centimeters
this.__repeatPerCentimeterX = null;
this.__repeatPerCentimeterY = null;
this.__colorTexture = null;
this.__normalTexture = null;
this.__roughnessTexture = null;
this.__ambientTexture = null;
this.__bumpTexture = null;
this.__metalTexture = null;
// this.__applyNewTextures();
// this.normalScale.set(-10, 10);
this.textureMapPack = textureMapPack;
}
__updateColorMap(texture) {
if (this.__colorTexture) {
this.__colorTexture.encoding = sRGBEncoding;
this.__colorTexture.wrapS = this.__colorTexture.wrapT = RepeatWrapping;
this.__colorTexture.repeat.set(this.__uRatio, this.__vRatio);
this.__colorTexture.needsUpdate = true;
this.map = this.__colorTexture;
}
this.__updateTextures();
}
__updateNormalMap(texture) {
if (this.__normalTexture) {
this.__normalTexture.encoding = sRGBEncoding;
this.__normalTexture.wrapS = this.__normalTexture.wrapT = RepeatWrapping;
this.__normalTexture.repeat.set(this.__uRatio, this.__vRatio);
this.__normalTexture.needsUpdate = true;
this.normalMap = this.__normalTexture;
}
this.__updateTextures();
}
__updateRoughnessMap(texture) {
if (this.__roughnessTexture) {
this.__roughnessTexture.encoding = sRGBEncoding;
this.__roughnessTexture.wrapS = this.__roughnessTexture.wrapT = RepeatWrapping;
this.__roughnessTexture.repeat.set(this.__uRatio, this.__vRatio);
this.__roughnessTexture.needsUpdate = true;
this.roughnessMap = this.__roughnessTexture;
}
this.__updateTextures();
}
__updateAmbientMap(texture) {
if (this.__ambientTexture) {
this.__ambientTexture.encoding = sRGBEncoding;
this.__ambientTexture.wrapS = this.__ambientTexture.wrapT = RepeatWrapping;
this.__ambientTexture.repeat.set(this.__uRatio, this.__vRatio);
this.__ambientTexture.needsUpdate = true;
this.aoMap = this.__ambientTexture;
// this.aoMapIntensity = 1.0;
}
this.__updateTextures();
}
__updateMetallicMap(texture) {
if (this.__metalTexture) {
this.__metalTexture.encoding = sRGBEncoding;
this.__metalTexture.wrapS = this.__metalTexture.wrapT = RepeatWrapping;
this.__metalTexture.repeat.set(this.__uRatio, this.__vRatio);
this.__metalTexture.needsUpdate = true;
this.metalnessMap = this.__metalTexture;
}
this.__updateTextures();
}
__updateBumpMap(texture) {
if (this.__bumpTexture) {
this.__bumpTexture.encoding = sRGBEncoding;
this.__bumpTexture.wrapS = this.__bumpTexture.wrapT = RepeatWrapping;
this.__bumpTexture.repeat.set(this.__uRatio, this.__vRatio);
this.__bumpTexture.needsUpdate = true;
this.displacementMap = this.__bumpTexture;
this.displacementMap.needsUpdate = true;
}
this.__updateTextures();
}
__updateTextures() {
this.needsUpdate = true;
this.__scene.needsUpdate = true;
}
__applyNewTextures() {
this.map = this.__colorTexture = null;
this.normalMap = this.__normalTexture = null;
this.roughnessMap = this.__roughnessTexture = null;
this.aoMap = this.__ambientTexture = null;
this.metalnessMap = this.__metalTexture = null;
this.displacementMap = this.__bumpTexture = null;
if (this.__textureMapPack.colormap) {
this.__colorTexture = new TextureLoader().load(this.__textureMapPack.colormap, this.__updateColorMap.bind(this));
}
if (this.__textureMapPack.normalmap) {
this.__normalTexture = new TextureLoader().load(this.__textureMapPack.normalmap, this.__updateNormalMap.bind(this));
}
if (this.__textureMapPack.roughnessmap) {
this.__roughnessTexture = new TextureLoader().load(this.__textureMapPack.roughnessmap, this.__updateRoughnessMap.bind(this));
}
if (this.__textureMapPack.ambientmap) {
this.__ambientTexture = new TextureLoader().load(this.__textureMapPack.ambientmap, this.__updateAmbientMap.bind(this));
}
if (this.__textureMapPack.metalmap) {
this.__metalTexture = new TextureLoader().load(this.__textureMapPack.metalmap, this.__updateMetallicMap.bind(this));
}
// if (this.__textureMapPack.bumpmap) {
// console.log('APPLY DISPLACEMENT MAP ::: ');
// this.__bumpTexture = new TextureLoader().load(this.__textureMapPack.bumpmap, this.__updateTextures.bind(this));
// this.displacementMap = this.__bumpTexture;
// this.displacementBias = -0.001;
// this.displacementScale = -100;
// }
}
__scaleUV(uRatio, vRatio) {
this.__uRatio = uRatio;
this.__vRatio = vRatio;
this.__updateColorMap();
this.__updateNormalMap();
this.__updateRoughnessMap();
this.__updateMetallicMap();
this.__updateAmbientMap();
this.__updateBumpMap();
// this.__updateTextures();
// this.needsUpdate = true;
// this.__scene.needsUpdate = true;
}
/**
*
* @param {Number} x - Always implies the direction of the width
* @param {Number} y - Can be either length or height depending if wall or floor using this texture
*/
__updateDimensions(width, height) {
let ur = Math.max(width * this.__repeatPerCentimeter, 1.0);
let vr = Math.max(height * this.__repeatPerCentimeter, 1.0);
this.__scaleUV(ur, vr);
}
get envMapCamera() {
return this.__mirrorCamera;
}
get textureMapPack() {
return this.__textureMapPack;
}
set textureMapPack(textureMapPack) {
this.__textureMapPack = textureMapPack;
textureMapPack.color = textureMapPack.color || '#FFFFFF';
textureMapPack.emissive = textureMapPack.emissive || '#000000';
textureMapPack.reflective = textureMapPack.reflective || 0.5;
textureMapPack.shininess = textureMapPack.shininess || 0.5;
this.color = new Color(textureMapPack.color);
this.emissive = new Color(textureMapPack.emissive);
this.roughness = textureMapPack.reflective;
this.metalness = textureMapPack.shininess;
this.__repeat = (!textureMapPack.repeat) ? TEXTURE_DEFAULT_REPEAT : textureMapPack.repeat;
this.__repeatPerCentimeter = 1.0 / this.__repeat;
this.__repeatX = textureMapPack.repeatX || textureMapPack.repeat;
this.__repeatY = textureMapPack.repeatY || textureMapPack.repeat;
this.__repeatPerCentimeterX = 1.0 / this.__repeatX;
this.__repeatPerCentimeterY = 1.0 / this.__repeatY;
this.__applyNewTextures();
}
get repeat() {
return this.__repeat;
}
// set repeat(value) {
// this.__repeat = value;
// this.__repeatPerCentimeter = 1.0 / this.__repeat;
// this.__updateDimensions(this.__dimensions.x, this.__dimensions.y);
// }
get dimensions() {
return this.__dimensions;
}
set dimensions(vec2) {
this.__dimensions = vec2.clone();
this.__updateDimensions(this.__dimensions.x, this.__dimensions.y);
}
get isReflective() {
return this.__reflectsScene;
}
get textureColor(){
return this.__textureMapPack.color;
}
set textureColor(hexstring){
this.__textureMapPack.color = hexstring;
this.color = new Color(this.__textureMapPack.color);
}
}

7
src/blueprint/scripts/materials/WallMaterial3D.js

@ -0,0 +1,7 @@
import { Material3D } from "./Material3D";
export class WallMaterial3D extends Material3D {
constructor(parameters, textureMapPack, scene) {
super(parameters, textureMapPack, scene, false);
}
}

172
src/blueprint/scripts/model/boundary.ts

@ -0,0 +1,172 @@
import { EventDispatcher } from "three";
import inside from 'point-in-polygon'
import alpha_shape from 'alpha-shape'
import { EVENT_BOUNDARY_UPDATE, EVENT_EXTERNAL_FLOORPLAN_LOADED } from "../core/EventSystem"
export class Boundary extends EventDispatcher {
constructor(floorplan, boundaryMetaData = {}) {
super();
this.__floorplan = floorplan;
this.__metadata = { style: { type: 'color', color: '#00FF00', repeat: 50, colormap: null } };
this.__boundaryRegions = [];
this.__boundaryRegionsRAW = [];
this.__roomRegions = [];
this.__roomRegionsRaw = [];
this.__externalRegions = [];
this.__externalRegionsRaw = [];
this.__width = 1.0;
this.__height = 1.0;
this.__externalDesignEvent = this.__externalDesignBoundaries.bind(this);
for (var opt in this.__metadata) {
if (this.__metadata.hasOwnProperty(opt) && boundaryMetaData.hasOwnProperty(opt)) {
this.__metadata[opt] = boundaryMetaData[opt];
}
}
this.__isValid = true;
this.__floorplan.addEventListener(EVENT_EXTERNAL_FLOORPLAN_LOADED, this.__externalDesignEvent);
}
__externalDesignBoundaries(evt) {
let i = 0;
let pts = [], ptsraw = [];
this.__externalRegions = [];
this.__externalRegionsRaw = [];
for (i = 0; i < this.__floorplan.externalCorners.length; i++) {
let c = this.__floorplan.externalCorners[i];
pts.push(c.location.clone());
ptsraw.push([c.location.x, c.location.y]);
}
let concave_hull = alpha_shape(0.1, ptsraw);
this.__externalRegionsRaw.push(ptsraw);
console.log(ptsraw);
console.log(concave_hull);
}
containsPoint(x, y, excludeBoundaryIndex = -1) {
let flag = true;
let i = 0, j = 0;
for (i = 0; i < this.__boundaryRegionsRAW.length; i++) {
if (i == excludeBoundaryIndex) {
continue;
}
let pts = this.__boundaryRegionsRAW[i];
let isInside = inside([x, y], pts);
flag &= isInside;
}
return flag;
}
intersectsExternalDesign(x, y) {
let flag = false;
let i = 0;
for (i = 0; i < this.__externalRegionsRaw.length; i++) {
let pts = this.__externalRegionsRaw[i];
let isInside = inside([x, y], pts);
flag |= isInside;
}
return flag;
}
update() {
}
clearBoundaryRegions() {
this.__boundaryRegions = [];
this.__boundaryRegionsRAW = []
}
addBoundaryRegion(points) {
let minX = Number.MAX_VALUE;
let minY = Number.MAX_VALUE;
let maxX = -Number.MAX_VALUE;
let maxY = -Number.MAX_VALUE;
let pts = points;
let ptsraw = [];
let i = 0;
for (i = 0; i < pts.length; i++) {
let point = pts[i];
minX = Math.min(minX, point.x);
minY = Math.min(minY, point.y);
maxX = Math.max(maxX, point.x);
maxY = Math.max(maxY, point.y);
ptsraw.push([point.x, point.y]);
}
this.__width = maxX - minX;
this.__height = maxY - minY;
this.__boundaryRegions.push(points);
this.__boundaryRegionsRAW.push(ptsraw);
}
get width() {
return this.__width;
}
get height() {
return this.__height;
}
get points() {
return (this.__boundaryRegions.length) ? this.__boundaryRegions[0] : [];
}
get styleRepeat() {
return this.__metadata.style.repeat;
}
/**
* return if style type is color or texture
*/
get styleType() {
return this.__metadata.style.type;
}
set styleType(type) {
this.__metadata.style.type = type;
}
get style() {
return this.__metadata.style;
}
/**
* return a hexacolor string if styleType is color
* return a path to the ground texture if styleType is texture
*/
get styleValue() {
return this.__metadata.style.value;
}
set styleValue(value) {
this.__metadata.style.value = value;
}
get isValid() {
return this.__isValid;
}
get metadata() {
return this.__metadata;
}
set metadata(mdata) {
for (let opt in this.__metadata) {
if (this.__metadata.hasOwnProperty(opt) && mdata.hasOwnProperty(opt)) {
this.__metadata[opt] = mdata[opt];
console.log('OPTION :: ', opt, ', VALUE :: ', mdata[opt]);
}
}
this.dispatchEvent({ type: EVENT_BOUNDARY_UPDATE, item: this });
}
}

696
src/blueprint/scripts/model/corner.ts

@ -0,0 +1,696 @@
import { EVENT_ACTION, EVENT_DELETED, EVENT_MOVED, EVENT_CORNER_ATTRIBUTES_CHANGED } from '../core/EventSystem.js';
import { Utils } from '../core/utils.js';
import { WallTypes } from '../core/constants.js';
//import {Dimensioning} from '../core/dimensioning.js';
import { Configuration, configWallHeight, cornerTolerance } from '../core/configuration.js';
/**
*
*/
export class Corner extends EventDispatcher {
/** Constructs a corner.
* @param {} floorplan The associated model floorplan.
* @param {Number} x X coordinate.
* @param {Number} y Y coordinate.
* @param {String} id An optional unique id. If not set, created internally.
*/
constructor(floorplan: Floorplan, x, y, id) {
super();
/**
* @property {String} id The id of this corner. Autogenerated the first time
* @type {String}
**/
this.id = id || Utils.guide();
/** @property {Array} wallStarts Array of walls that are start walls
* @type {Array}
**/
this.wallStarts = [];
/** @property {Array} wallEnds Array of walls that are end walls
* @type {Array}
**/
this.wallEnds = [];
/**
* @deprecated Not in use. The EventDispatcher from threejs is used for emit and listen events
**/
this.moved_callbacks = null;
/**
* @deprecated Not in use. The EventDispatcher from threejs is used for emit and listen events
**/
this.deleted_callbacks = null;
/**
* @deprecated Not in use. The EventDispatcher from threejs is used for emit and listen events
**/
this.action_callbacks = null;
/**
* @property {Floorplan} floorplan Reference to the model floorplan
* @type {Floorplan}
**/
this.floorplan = floorplan;
/**
* @property {Number} x The position in x dimension
* @type {Number}
**/
this._x = x;
/**
* @property {Number} y The position in y dimension
* @type {Number}
**/
this._y = y;
/**
* @property {Vector2} co The position as Vector2
* @type {Vector2}
* @see https://threejs.org/docs/#api/en/math/Vector2
**/
this._co = new Vector2(this._x, this._y);
/**
* @property {Number} _elevation The elevation at this corner
* @type {Number}
**/
this._elevation = Configuration.getNumericValue(configWallHeight);
/**
* @property {Array} attachedRooms Array of rooms that have walls using this corner
* @type {Array}
**/
this.attachedRooms = [];
this.__hasBeenRemoved = false;
this._angles = [];
this._angleDirections = [];
this._startAngles = [];
this._endAngles = [];
this._cyclicNeighbors = [];
/**
* @property {Boolean} _hasChanged A flag to indicate if something has changed about this corner
* @type {Boolean}
**/
this._hasChanged = false;
this.__isLocked = false;
}
set isLocked(flag) {
this.__isLocked = flag;
}
get isLocked() {
return this.__isLocked;
}
get uuid() {
return this.id;
}
get startAngles() {
return this._startAngles;
}
get endAngles() {
return this._endAngles;
}
get angles() {
return this._angles;
}
get angleDirections() {
return this._angleDirections;
}
get location() {
return this._co;
}
set location(xy) {
this._co.x = xy.x;
this._co.y = xy.y;
this.x = xy.x;
this.y = xy.y;
}
get x() {
return this._x;
}
set x(value) {
let oldvalue = this._x;
if (Math.abs(value - this._x) > 1e-6) {
this._hasChanged = true;
}
this._x = value;
if (this._hasChanged) {
this._co.x = this._x;
this.updateAttachedRooms();
// this.floorplan.update(false);
this.dispatchEvent({ type: EVENT_CORNER_ATTRIBUTES_CHANGED, item: this, info: { from: oldvalue, to: this._x } });
}
}
get y() {
return this._y;
}
set y(value) {
let oldvalue = this._y;
if (Math.abs(value - this._y) > 1e-6) {
this._hasChanged = true;
}
this._y = value;
if (this._hasChanged) {
this._co.y = this._y;
this.updateAttachedRooms();
// this.floorplan.update(false);
this.dispatchEvent({ type: EVENT_CORNER_ATTRIBUTES_CHANGED, item: this, info: { from: oldvalue, to: this._y } });
}
}
/** @type {Number} elevation The elevation value at this corner*/
set elevation(value) {
let oldvalue = this._elevation;
if ((value - this._elevation) > 1e-6) {
this._hasChanged = true;
}
this._elevation = Number(value); //Dimensioning.cmFromMeasureRaw(Number(value));
if (this._hasChanged) {
this.dispatchEvent({ type: EVENT_CORNER_ATTRIBUTES_CHANGED, item: this, info: { from: oldvalue, to: this._elevation } });
}
}
/** @type {Number} elevation The elevation value at this corner*/
get elevation() {
return this._elevation;
}
/**
* @param {Room} room - The room that should be attached to this corner
* @return {void}
*/
attachRoom(room) {
if (room) {
this.attachedRooms.push(room);
}
}
/**
* @return {Room[]} Array of rooms attached to this corner
*/
getAttachedRooms() {
return this.attachedRooms;
}
/**
* @return {void} Clear all the rooms attached to this corner
*/
clearAttachedRooms() {
this.attachedRooms = [];
}
/** Add function to moved callbacks.
* @param func The function to be added.
*/
fireOnMove(func) {
this.moved_callbacks.add(func);
}
/** Add function to deleted callbacks.
* @param func The function to be added.
*/
fireOnDelete(func) {
this.deleted_callbacks.add(func);
}
/** Add function to action callbacks.
* @param func The function to be added.
*/
fireOnAction(func) {
this.action_callbacks.add(func);
}
fireAction(action) {
this.dispatchEvent({ type: EVENT_ACTION, item: this, action: action });
// this.action_callbacks.fire(action)
}
/**
* @returns
* @deprecated
*/
getX() {
return this.x;
}
/**
* @returns
* @deprecated
*/
getY() {
return this.y;
}
/**
* @param {Number} tolerance - The tolerance value within which it will snap to adjacent corners
* @return {Object} snapped Contains keys x and y with true/false values
* @description The object with x and y that are boolean values to indicate if the snap happens in x and y
*/
snapToAxis(tolerance) {
// try to snap this corner to an axis
let snapped = { x: false, y: false };
let scope = this;
this.adjacentCorners().forEach((corner) => {
if (Math.abs(corner.x - scope.x) < tolerance) {
scope.x = corner.x;
snapped.x = true;
}
if (Math.abs(corner.y - scope.y) < tolerance) {
scope.y = corner.y;
snapped.y = true;
}
});
return snapped;
}
/** Moves corner to new position.
* @param {Number} newX The new x position.
* @param {Number} newY The new y position.
*/
move(newX, newY, mergeWithIntersections = false) {
// this.x = newX;
// this.y = newY;
this._x = newX;
this._y = newY;
this._co.x = newX;
this._co.y = newY;
if (mergeWithIntersections) {
//The below line is crashing after makign the changes for curved walls
//While release v1.0.0 is stable even with this line enabled
this.mergeWithIntersected();
if (this.floorplan.rooms.length < 10) {
this.updateAttachedRooms(true);
}
}
// this.wallStarts.forEach((wall) => {
// wall.fireMoved();
// });
// this.wallEnds.forEach((wall) => {
// wall.fireMoved();
// });
this.dispatchEvent({ type: EVENT_MOVED, item: this, position: new Vector2(newX, newY) });
}
/** Moves corner relatively to new position.
* @param {Number} dx The delta x.
* @param {Number} dy The delta y.
*/
relativeMove(dx, dy) {
this.move(this.x + dx, this.y + dy);
}
/**
* Dispatches an event when removed from the floorplan({@link Floorplan}) instance. The event object contains reference to this {@link Corner} instance as item.
* @example
* let corner = new Corner(floorplan, 0, 0);
* function cornerRemoved(e) { console.log('I WAS REMOVED FROM LOCATION ', e.item.x, e.item.y) };
* corner.remove();
* @emits {EVENT_DELETED}
**/
remove() {
this.__hasBeenRemoved = true;
this.dispatchEvent({ type: EVENT_DELETED, item: this });
}
/**
* Removes all the connected corners and itself. This in essence removes all the walls({@link Wall}) this corner is connected to.
* @example
* let corner1 = new Corner(floorplan, 0, 0);
* let corner2 = new Corner(floorplan, 10, 0);
* function cornerRemoved(e) { console.log('I WAS REMOVED FROM LOCATION ', e.item.x, e.item.y) } //Will log twice for two corners;
* corner.removeAll();
**/
removeAll() {
let i = 0;
for (i = 0; i < this.wallStarts.length; i++) {
this.wallStarts[i].remove();
}
for (i = 0; i < this.wallEnds.length; i++) {
this.wallEnds[i].remove();
}
this.remove();
}
//Angle is in degrees 0 - 360
closestAngle(angle) {
let neighbors = this.adjacentCorners();
let delta = 999999;
let closestAngle = 0;
let point = new Vector2();
for (let i = 0; i < neighbors.length; i++) {
let wall = this.wallToOrFrom(neighbors[i]);
if (wall.wallType === WallTypes.CURVED) {
continue;
}
let neighbourAngle = neighbors[i].location.clone().sub(this.location).angle();
neighbourAngle = (neighbourAngle * 180) / Math.PI;
let diff = Math.abs(angle - neighbourAngle);
if (diff < delta) {
delta = diff;
point.x = neighbors[i].location.x;
point.y = neighbors[i].location.y;
closestAngle = neighbourAngle;
}
}
return { angle: closestAngle, point: point };
}
updateAngles() {
let neighbors = this.adjacentCorners();
this._angles = [];
this._angleDirections = [];
this._startAngles = [];
this._endAngles = [];
this._cyclicNeighbors = [];
if (neighbors.length < 2) {
return;
}
let start = this.location.clone();
let points = [];
for (let i = 0; i < neighbors.length; i++) {
points.push(neighbors[i].location);
}
let indicesAndAngles = Utils.getCyclicOrder(points, start);
let indices = indicesAndAngles['indices'];
let angles = indicesAndAngles['angles'];
// var N = (indices.length%2 === 0)? (indices.length < 3) ? indices.length - 1 : indices.length : indices.length - 1;
let N = (indices.length < 3) ? 1 : indices.length;
for (let i = 0; i < N; i++) {
let next = (i + 1) % indices.length;
let cindex = indices[i];
let nindex = indices[next];
let cwall = this.wallToOrFrom(neighbors[cindex]);
let nwall = this.wallToOrFrom(neighbors[nindex]);
if (cwall != null && nwall != null) {
if (cwall.wallType === WallTypes.CURVED || nwall.wallType === WallTypes.CURVED) {
// No use in showing angle between two curved or two walls with intermixed types of straight and curved
// Set everything to zero
this._startAngles.push(0);
this._endAngles.push(0);
this._angles.push(0);
this._angleDirections.push(new Vector2(0, 0));
this._cyclicNeighbors.push(neighbors[indices[i]]);
continue;
}
}
let vectorA = points[cindex].clone().sub(start).normalize();
let vectorB = points[nindex].clone().sub(start).normalize();
let midVector = vectorA.add(vectorB).multiplyScalar(20.0);
let diffAngle = Math.abs(angles[next] - angles[i]);
diffAngle = (diffAngle > 180) ? 360 - diffAngle : diffAngle;
diffAngle = Math.round(diffAngle * 10) / 10;
this._startAngles.push(angles[i]);
this._endAngles.push(angles[next]);
this._angles.push(diffAngle);
this._angleDirections.push(midVector);
this._cyclicNeighbors.push(neighbors[indices[i]]);
}
}
/**
* When a corner is moved from its location it will impact the connected rooms ({@link Room}) shape, thus their areas. This will update the rooms
* @example
* let corner = new Corner(floorplan, 0, 0);
* corner.move(10, 0);
**/
updateAttachedRooms(explicit = false) {
if (!this._hasChanged && !explicit) {
return;
}
// console.log('UPDATE ALL ATTACHED ROOMS :: ');
this.attachedRooms.forEach((room) => {
room.updateArea();
});
this._hasChanged = false;
}
/** Gets the adjacent corners that are connected to this corner by walls ({@link Wall}).
* @returns {Corner[]} Array of corners.
*/
adjacentCorners() {
let retArray = [];
let i = 0;
for (i = 0; i < this.wallStarts.length; i++) {
retArray.push(this.wallStarts[i].getEnd());
}
for (i = 0; i < this.wallEnds.length; i++) {
retArray.push(this.wallEnds[i].getStart());
}
return retArray;
}
/** Checks if a wall is connected.
* @param {Wall} wall A wall.
* @returns {boolean} in case of connection.
*/
isWallConnected(wall) {
let i = 0;
for (i = 0; i < this.wallStarts.length; i++) {
if (this.wallStarts[i] === wall) {
return true;
}
}
for (i = 0; i < this.wallEnds.length; i++) {
if (this.wallEnds[i] === wall) {
return true;
}
}
return false;
}
/**
* Returns the distance between this corner and a point in 2d space
* @param {Vector2} point
* @see https://threejs.org/docs/#api/en/math/Vector2
* @return {Number} distance The distance
**/
distanceFrom(point) {
let distance = Utils.distance(point, new Vector2(this.x, this.y));
//console.log('x,y ' + x + ',' + y + ' to ' + this.getX() + ',' + this.getY() + ' is ' + distance);
return distance;
}
/** Gets the distance from a wall.
* @param {Wall} wall A wall.
* @returns {Number} distance The distance.
*/
distanceFromWall(wall) {
let cPoint = new Vector2(this.x, this.y);
if (wall.wallType === WallTypes.STRAIGHT) {
return wall.distanceFrom(cPoint);
} else if (wall.wallType === WallTypes.CURVED) {
let p = wall.bezier.project(cPoint);
let projected = new Vector2(p.x, p.y);
return projected.distanceTo(cPoint);
}
}
/** Gets the distance from a corner.
* @param {Corner} corner A corner.
* @returns {Number} The distance.
*/
distanceFromCorner(corner) {
return this.distanceFrom(new Vector2(corner.x, corner.y));
}
/** Detaches a wall.
* @param {Wall} wall A wall.
*/
detachWall(wall) {
Utils.removeValue(this.wallStarts, wall);
Utils.removeValue(this.wallEnds, wall);
/**
* If there are no walls connected to this corner then it is not
* necessary to keep this corner around anymore as an orphan point.
* But ensure you check if this corner has already been removed. Otherwise
* it will be lead to recursion
*/
if (this.wallStarts.length === 0 && this.wallEnds.length === 0 && !this.__hasBeenRemoved) {
this.remove();
}
}
/** Attaches a start wall.
* @param {Wall} wall A wall.
*/
attachStart(wall) {
this.wallStarts.push(wall);
}
/** Attaches an end wall.
* @param {Wall} wall A wall.
*/
attachEnd(wall) {
this.wallEnds.push(wall);
}
/** Get wall to corner.
* @param {Corner} corner A corner.
* @return {Wall} The associated wall or null.
*/
wallTo(corner) {
for (let i = 0; i < this.wallStarts.length; i++) {
if (this.wallStarts[i].getEnd() === corner) {
return this.wallStarts[i];
}
}
return null;
}
/** Get wall from corner.
* @param {Corner} corner A corner.
* @return {Wall} The associated wall or null.
*/
wallFrom(corner) {
for (let i = 0; i < this.wallEnds.length; i++) {
if (this.wallEnds[i].getStart() === corner) {
return this.wallEnds[i];
}
}
return null;
}
/** Get wall to or from corner.
* @param {Corner} corner A corner.
* @return {Wall} The associated wall or null.
*/
wallToOrFrom(corner) {
return this.wallTo(corner) || this.wallFrom(corner);
}
/** Get wall from corner.
* @param {Corner} corner A corner.
*/
combineWithCorner(corner) {
let i = 0;
// update position to other corner's
// this.x = corner.x;
// this.y = corner.y;
this.move(corner.x, corner.y, false);
// absorb the other corner's wallStarts and wallEnds
for (i = corner.wallStarts.length - 1; i >= 0; i--) {
corner.wallStarts[i].setStart(this);
}
for (i = corner.wallEnds.length - 1; i >= 0; i--) {
corner.wallEnds[i].setEnd(this);
}
let rooms = corner.getAttachedRooms();
for (i = 0; i < rooms.length; i++) {
let room = rooms[i];
//Below returns the roomname object
let roomname = this.floorplan.metaroomsdata[room.roomByCornersId];
if (roomname) {
let oldId = room.roomByCornersId;
let newId = oldId.replace(corner.id, this.id);
this.floorplan.metaroomsdata[newId] = {};
this.floorplan.metaroomsdata[newId]['name'] = roomname['name'];
delete this.floorplan.metaroomsdata[oldId];
}
}
// delete the other corner
corner.removeAll();
this.removeDuplicateWalls();
this.floorplan.update();
}
mergeWithIntersected(updateFloorPlan = true) {
let i = 0;
//console.log('mergeWithIntersected for object: ' + this.type);
// check corners
for (i = 0; i < this.floorplan.getCorners().length; i++) {
let corner = this.floorplan.getCorners()[i];
if (this.distanceFromCorner(corner) < cornerTolerance && corner !== this) {
this.combineWithCorner(corner);
return true;
}
}
// check walls
for (i = 0; i < this.floorplan.getWalls().length; i++) {
let wall = this.floorplan.getWalls()[i];
if (this.distanceFromWall(wall) < cornerTolerance && !this.isWallConnected(wall)) {
// update position to be on wall
let intersection;
if (wall.wallType === WallTypes.STRAIGHT) {
intersection = Utils.closestPointOnLine(new Vector2(this.x, this.y), wall.getStart(), wall.getEnd());
} else if (wall.wallType === WallTypes.CURVED) {
intersection = wall.bezier.project(new Vector2(this.x, this.y));
}
if (wall.wallType === WallTypes.STRAIGHT) {
// merge this corner into wall by breaking wall into two parts
let newWall = this.floorplan.newWall(this, wall.getEnd());
wall.setEnd(this);
newWall.clearAttachedRooms();
wall.clearAttachedRooms();
} else if (wall.wallType === WallTypes.CURVED) {
// merge this corner into wall by breaking wall into two parts
let newWall = this.floorplan.newWall(this, wall.getEnd());
wall.setEnd(this);
newWall.clearAttachedRooms();
wall.clearAttachedRooms();
}
//The below line is crashing because of recursive. This function mergeWithIntersected is called
//From move(newX, newY) method. Now if we call move(newX, newY) from inside this method
//It will lead to recursion. So ensure in the move(newX, newY) method mergeWithIntersected is not called
//Hence added a third parameter to move(newX, newY, mergeWithIntersections) that is a boolean value
//Send this boolean value as false to avoid recursion crashing of the application
this.move(intersection.x, intersection.y, false, updateFloorPlan); //Causes Recursion if third parameter is true
this.floorplan.update();
return true;
}
}
return false;
}
/** Ensure we do not have duplicate walls (i.e. same start and end points) */
removeDuplicateWalls() {
let i = 0;
// delete the wall between these corners, if it exists
let wallEndpoints = {};
let wallStartpoints = {};
for (i = this.wallStarts.length - 1; i >= 0; i--) {
if (this.wallStarts[i].getEnd() === this) {
// remove zero length wall
this.wallStarts[i].remove();
} else if (this.wallStarts[i].getEnd().id in wallEndpoints) {
// remove duplicated wall
this.wallStarts[i].remove();
} else {
wallEndpoints[this.wallStarts[i].getEnd().id] = true;
}
}
for (i = this.wallEnds.length - 1; i >= 0; i--) {
if (this.wallEnds[i].getStart() === this) {
// removed zero length wall
this.wallEnds[i].remove();
} else if (this.wallEnds[i].getStart().id in wallStartpoints) {
// removed duplicated wall
this.wallEnds[i].remove();
} else {
wallStartpoints[this.wallEnds[i].getStart().id] = true;
}
}
}
}

222
src/blueprint/scripts/model/cornergroups.ts

@ -0,0 +1,222 @@
import { Vector2, Matrix4, Vector3 } from "three";
import { EVENT_MOVED } from "../core/EventSystem";
export class CornerGroup {
/**
*
* @param {Array} array of corners instances
*/
constructor(corners) {
this.__corners = corners;
this.__size = new Vector2();
this.__center = null;
this.__currentCenter = new Vector2();
this.__deltaTranslation = new Vector2();
this.__radians = 0.0;
this.__originalCornerPositions = null;
this.__tl = null;
this.__br = null;
this.__tr = null;
this.__bl = null;
this.__matrix = new Matrix4();
this.__cornerMovedEvent = this.__cornerMoved.bind(this);
this.__addCornerListeners();
this.__update();
}
__cornerMoved() {
// this.__update();
}
__addCornerListeners() {
for (let i = 0; i < this.__corners.length; i++) {
this.__corners[i].addEventListener(EVENT_MOVED, this.__cornerMovedEvent);
}
}
__update() {
this.__originalCornerPositions = [];
let minPoint = new Vector2(Number.MAX_VALUE, Number.MAX_VALUE);
let maxPoint = new Vector2(-Number.MAX_VALUE, -Number.MAX_VALUE);
for (let i = 0; i < this.__corners.length; i++) {
let corner = this.__corners[i];
minPoint.x = Math.min(minPoint.x, corner.location.x);
minPoint.y = Math.min(minPoint.y, corner.location.y);
maxPoint.x = Math.max(maxPoint.x, corner.location.x);
maxPoint.y = Math.max(maxPoint.y, corner.location.y);
this.__originalCornerPositions.push(corner.location.clone());
}
this.__minPoint = minPoint.clone();
this.__maxPoint = maxPoint.clone();
this.__size = maxPoint.clone().sub(minPoint);
this.__size.x = Math.abs(this.__size.x);
this.__size.y = Math.abs(this.__size.y);
// if (!this.__center) {
this.__center = this.__size.clone().multiplyScalar(0.5).add(minPoint);
// }
this.__currentCenter = this.__size.clone().multiplyScalar(0.5).add(minPoint);
this.__matrix = this.__matrix.identity();
}
__applyTransformations(scale, radians, origin) {
let translation = origin.clone().sub(this.__center);
let translationMatrix = new Matrix4().makeTranslation(translation.x, translation.y, 0);
let T = new Matrix4().makeTranslation(-origin.x, -origin.y, 0); //Translate to -origin of scaling
let TInv = new Matrix4().makeTranslation(origin.x, origin.y, 0); //Translate to origin of scaling (inverse)
let rotationMatrix = TInv.clone().multiply(new Matrix4().makeRotationAxis(new Vector3(0, 0, 1), radians)).multiply(T);
let scaleMatrix = TInv.clone().multiply(new Matrix4().makeScale(scale.x, scale.y, 1)).multiply(T);
let transformMatrix = rotationMatrix.multiply(scaleMatrix).multiply(translationMatrix);
let i = 0;
for (i = 0; i < this.__corners.length; i++) {
let location = this.__originalCornerPositions[i].clone();
let location3 = new Vector3(location.x, location.y, 0);
location3.applyMatrix4(transformMatrix);
// this.__corners[i].location = new Vector2(location3.x, location3.y);
this.__corners[i].move(location3.x, location3.y);
}
// if (this.__corners[0]) {
// this.__corners[0].floorplan.update();
// }
}
applyTransformations(scale, radians, origin) {
this.__applyTransformations(scale, radians, origin);
}
contains(corner) {
for (let i = 0; i < this.__corners.length; i++) {
if (corner.id === this.__corners[i].id) {
return true;
}
}
return false;
// return Utils.hasValue(this.__corners, corner);
}
update() {
this.__update();
}
destroy() {
for (let i = 0; i < this.__corners.length; i++) {
this.__corners[i].removeEventListener(EVENT_MOVED, this.__cornerMovedEvent);
}
this.__corners = [];
}
get matrix() {
return this.__matrix;
}
set matrix(mat) {
this.__matrix = mat;
}
get corners() {
return this.__corners;
}
get size() {
return this.__size.clone();
}
get center() {
return this.__center.clone();
}
get boundary() {
let points = [];
for (let i = 0; i < this.__corners.length; i++) {
let corner = this.__corners[i];
points.push([corner.location.x, corner.location.y]);
}
return points;
}
}
export class CornerGroups {
/**
*
* @param {Floorplan} floorplan
* @description A class that groups connected corners together and also helps to \
* to apply transformations on them
*
*/
constructor(floorplan) {
this.__groups = [];
this.__floorplan = floorplan;
this.createGroups();
}
getContainingGroup(corner) {
for (let i = 0; i < this.__groups.length; i++) {
if (this.__groups[i].contains(corner)) {
return this.__groups[i];
}
}
return null;
}
get groups() {
return this.__groups;
}
/**
* @description - Determine heuristically the connected group of corners
*/
createGroups() {
function tinyCornerGroups(corner, array) {
let adjacentCorners = corner.adjacentCorners();
//The below condition means this corner and its neighbors hasn't been analyzed
if (!array.includes(corner)) {
array.push(corner);
for (let j = 0; j < adjacentCorners.length; j++) {
array = tinyCornerGroups(adjacentCorners[j], array);
}
}
return array;
}
function tinyNotInArray(mainarray, subarray) {
for (let j = 0; j < mainarray.length; j++) {
if (!subarray.includes(mainarray[j])) {
return mainarray[j];
}
}
return null;
}
this.__groups.forEach((group) => {
group.destroy();
});
this.__groups.length = 0;
if (!this.__floorplan.corners.length) {
return;
}
let firstCorner = this.__floorplan.corners[0];
let cornerGroups = [
[]
];
cornerGroups[0] = tinyCornerGroups(firstCorner, cornerGroups[0]);
while (cornerGroups.flat().length !== this.__floorplan.corners.length) {
let isolatedCorner = tinyNotInArray(this.__floorplan.corners, cornerGroups.flat());
if (isolatedCorner) {
let index = cornerGroups.push([]) - 1;
cornerGroups[index] = tinyCornerGroups(isolatedCorner, cornerGroups[index]);
} else {
break;
}
}
for (let i = 0; i < cornerGroups.length; i++) {
let cornerGroup = new CornerGroup(cornerGroups[i]);
this.__groups.push(cornerGroup);
}
}
}

1298
src/blueprint/scripts/model/floorplan.ts

File diff suppressed because it is too large Load Diff

1028
src/blueprint/scripts/model/half_edge.ts

File diff suppressed because it is too large Load Diff

146
src/blueprint/scripts/model/model.ts

@ -0,0 +1,146 @@
import { EVENT_LOADED, EVENT_LOADING, EVENT_ITEM_REMOVED, EVENT_NEW_PARAMETRIC_ITEM, EVENT_NEW_ITEM, EVENT_MODE_RESET, EVENT_EXTERNAL_FLOORPLAN_LOADED } from '../core/EventSystem.js';
import { EventDispatcher } from 'three';
import { Floorplan } from './floorplan';
import { Utils } from '../core/utils.js';
import { Factory } from '../items/factory.js';
/**
* {@link Floorplan} {@link Scene}
*/
export class Model extends EventDispatcher {
__floorplan;
__roomItems;
textureDir;
scene;
/** Constructs a new model.
* @param textureDir The directory containing the textures.
*/
constructor(textureDir: string) {
super();
this.__floorplan = new Floorplan();
this.__roomItems = [];
this.textureDir = textureDir;
}
switchWireframe(flag) {
this.scene.switchWireframe(flag);
}
loadSerialized(json) {
// TODO: better documentation on serialization format.
// TODO: a much better serialization format.
this.dispatchEvent({ type: EVENT_LOADING, item: this });
// this.roomLoadingCallbacks.fire();
var data = JSON.parse(json);
this.newDesign(data.floorplan, data.items);
this.dispatchEvent({ type: EVENT_LOADED, item: this, });
}
loadLockedSerialized(json) {
var data = JSON.parse(json);
this.floorplan.loadLockedFloorplan(data.floorplan);
this.dispatchEvent({ type: EVENT_EXTERNAL_FLOORPLAN_LOADED, item: this, });
}
exportSerialized() {
let floorplanJSON = this.floorplan.saveFloorplan();
let roomItemsJSON = [];
this.__roomItems.forEach((item) => {
// item.updateMetadataExplicit();
roomItemsJSON.push(item.metadata);
});
var room = { floorplan: floorplanJSON, items: roomItemsJSON };
return JSON.stringify(room);
}
newDesign(floorplan, items) {
this.__roomItems = [];
this.floorplan.loadFloorplan(floorplan);
for (let i = 0; i < items.length; i++) {
let itemMetaData = items[i];
let itemType = itemMetaData.itemType;
let item = new (Factory.getClass(itemType))(itemMetaData, this, itemMetaData.id);
this.__roomItems.push(item);
}
}
reset() {
this.floorplan.reset();
this.__roomItems.length = 0;
this.dispatchEvent({ type: EVENT_MODE_RESET });
}
/** Gets the items.
* @returns The items.
*/
getItems() {
return this.__roomItems;
}
/** Gets the count of items.
* @returns The count.
*/
itemCount() {
return this.__roomItems.length;
}
/** Removes all items. */
clearItems() {
let scope = this;
this.__roomItems.forEach((item) => {
scope.removeItem(item, false);
});
this.__roomItems = [];
}
/**
* Removes an item.
* @param item The item to be removed.
* @param dontRemove If not set, also remove the item from the items list.
*/
removeItem(item, keepInList) {
// use this for item meshes
this.remove(item, keepInList);
this.dispatchEvent({ type: EVENT_ITEM_REMOVED, item: item });
}
/** Removes a non-item, basically a mesh, from the scene.
* @param mesh The mesh to be removed.
*/
remove(roomItem, keepInList) {
keepInList = keepInList || false;
if (!keepInList) {
roomItem.destroy();
Utils.removeValue(this.__roomItems, roomItem);
}
}
/**
* Creates an item and adds it to the scene.
* @param itemType The type of the item given by an enumerator.
* @param fileName The name of the file to load.
* @param metadata TODO
* @param position The initial position.
* @param rotation The initial rotation around the y axis.
* @param scale The initial scaling.
* @param fixed True if fixed.
* @param newItemDefinitions - Object with position and 'edge' attribute if it is a wall item
*/
addItemByMetaData(metadata) {
//TODO
this.dispatchEvent({ type: EVENT_NEW_ITEM, item: null });
}
addItem(item) {
this.__roomItems.push(item);
this.dispatchEvent({ type: EVENT_NEW_ITEM, item: item });
}
get roomItems() {
return this.__roomItems;
}
get floorplan() {
return this.__floorplan;
}
}

678
src/blueprint/scripts/model/room.ts

@ -0,0 +1,678 @@
import { EventDispatcher, Vector2, Vector3, Face3, Geometry, Shape, ShapeGeometry, Mesh, MeshBasicMaterial, DoubleSide, Box3 } from 'three';
import { Plane, Matrix4 } from 'three';
import { EVENT_CHANGED, EVENT_ROOM_ATTRIBUTES_CHANGED, EVENT_MOVED, EVENT_UPDATED, EVENT_UPDATE_TEXTURES, EVENT_CORNER_ATTRIBUTES_CHANGED, EVENT_MODIFY_TEXTURE_ATTRIBUTE } from '../core/EventSystem.js';
import { Region } from '../core/utils.js';
import { WallTypes, TEXTURE_DEFAULT_REPEAT, defaultFloorTexture } from '../core/constants.js';
import { Utils } from '../core/utils.js';
import { HalfEdge } from './half_edge.js';
import { BufferGeometry } from 'three/build/three.module';
/** Default texture to be used if nothing is provided. */
export const defaultRoomTexture = { url: 'rooms/textures/hardwood.png', scale: 400 };
/**
* A Room is the combination of a Floorplan with a floor plane.
*/
export class Room extends EventDispatcher {
_name = 'A New Room';
min = null;
max = null;
center = null;
area = 0.0;
areaCenter = null;
_polygonPoints = [];
__walls = [];
floorplan;
_corners;
interiorCorners = [];
interiorCorners3D = [];
floorRectangleSize = new Vector2();
edgePointer = null;
floorPlane = null;
roofPlane = null;
customTexture = false;
floorChangeCallbacks = null;
__destroyed = false;
__isLocked = false;
__roomUpdatedEvent;
__wallsChangedEvent;
_roomByCornersId;
/**
* ordered CCW
*/
constructor(floorplan, corners) {
super();
this._name = 'A New Room';
this.min = null;
this.max = null;
this.center = null;
this.area = 0.0;
this.areaCenter = null;
this._polygonPoints = [];
this.__walls = [];
this.floorplan = floorplan;
this._corners = corners;
this.interiorCorners = [];
this.interiorCorners3D = [];
this.floorRectangleSize = new Vector2();
this.edgePointer = null;
this.floorPlane = null;
this.roofPlane = null;
this.customTexture = false;
this.floorChangeCallbacks = null;
this.__destroyed = false;
this.__isLocked = false;
this.updateWalls();
this.updateInteriorCorners();
this.generateFloorPlane();
this.generateRoofPlane();
let cornerids = [];
let i = 0;
this.__roomUpdatedEvent = this._roomUpdated.bind(this);
this.__wallsChangedEvent = this.__wallsChanged.bind(this);
for (; i < this.corners.length; i++) {
let c = this.corners[i];
c.attachRoom(this);
cornerids.push(c.id);
c.addEventListener(EVENT_MOVED, this.__roomUpdatedEvent);
c.addEventListener(EVENT_CORNER_ATTRIBUTES_CHANGED, this.__roomUpdatedEvent);
}
for (i = 0; i < this.__walls.length; i++) {
let wall = this.__walls[i];
// wall.addRoom(this);
wall.addEventListener(EVENT_UPDATED, this.__wallsChangedEvent);
}
this._roomByCornersId = cornerids.join(',');
}
__wallsChanged(evt) {
this.dispatchEvent({ type: EVENT_CHANGED, item: this });
this.updateInteriorCorners();
}
_roomUpdated() {
this.updateInteriorCorners();
this.updateArea();
this.generateFloorPlane();
this.generateRoofPlane();
}
destroy() {
let i = 0;
for (; i < this.corners.length; i++) {
let c = this.corners[i];
c.removeEventListener(EVENT_MOVED, this.__roomUpdatedEvent);
}
for (i = 0; i < this.__walls.length; i++) {
let wall = this.__walls[i];
wall.removeEventListener(EVENT_UPDATED, this.__wallsChangedEvent);
}
this.__destroyed = true;
this.dispatchEvent({ type: EVENT_CHANGED, item: this });
}
__getOrderedCorners(wall) {
let i = this.corners.indexOf(wall.start);
let j = this.corners.indexOf(wall.end);
if (i === -1 || j === -1) {
return null;
}
let start = this.corners[Math.max(i, j)].location.clone();
let end = this.corners[Math.min(i, j)].location.clone();
if ((i === 0 && j === this.corners.length - 1) || (j === 0 && i === this.corners.length - 1)) {
end = this.corners[this.corners.length - 1].location.clone();
start = this.corners[0].location.clone();
}
return { 'start': start, 'end': end };
}
getWallDirection(wall) {
let orderedCorners = this.__getOrderedCorners(wall);
if (orderedCorners === null) {
return null;
}
let start = orderedCorners['start'];
let end = orderedCorners['end'];
let vect = end.sub(start);
let vect3 = new Vector3(vect.x, vect.y, 0);
return vect3.normalize().clone();
}
getWallOutDirection(wall) {
let vect3 = this.getWallDirection(wall); //new Vector3(vect.x, vect.y, 0);
if (vect3 === null) {
return null;
}
// console.log('WALL DIRECTION : ', vect3);
vect3 = vect3.applyAxisAngle(new Vector3(0, 0, 1), Math.PI * 0.5);
// console.log('WALL NORMAL DIRECTION : ', vect3);
return vect3.normalize();
}
getWallStart(wall) {
let orderedCorners = this.__getOrderedCorners(wall);
if (orderedCorners === null) {
return null;
}
return orderedCorners['start'];
}
getWallEnd(wall) {
let orderedCorners = this.__getOrderedCorners(wall);
if (orderedCorners === null) {
return null;
}
return orderedCorners['end'];
}
getWallPlane(wall) {
let orderedCorners = this.__getOrderedCorners(wall);
if (orderedCorners === null) {
return null;
}
let planeLocation = wall.start.location.clone().add(wall.end.location).multiplyScalar(0.5);
let normal = this.getWallOutDirection(wall);
let plane = new Plane(normal, 0);
let m = new Matrix4();
m.makeTranslation(planeLocation.x, planeLocation.y, 0);
// plane = plane.applyMatrix4(m);
plane.setFromNormalAndCoplanarPoint(normal, new Vector3(planeLocation.x, planeLocation.y, 0));
return plane;
}
roomIdentifier() {
let cornerids = [];
this.corners.forEach((corner) => {
cornerids.push(corner.id);
});
let ids = cornerids.join(',');
return ids;
}
getUuid() {
let cornerUuids = Utils.map(this.corners, function (c) { return c.id; });
cornerUuids.sort();
return cornerUuids.join();
}
fireOnFloorChange(callback) {
this.floorChangeCallbacks.add(callback);
}
setRoomWallsTexture(textureUrl, textureStretch, textureScale) {
let edge = this.edgePointer;
let iterateWhile = true;
edge.setTexture(textureUrl, textureStretch, textureScale);
while (iterateWhile) {
if (edge.next === this.edgePointer) {
break;
} else {
edge = edge.next;
}
edge.setTexture(textureUrl, textureStretch, textureScale);
}
}
/**
* @deprecated
* textureStretch always true, just an argument for consistency with walls
*/
setTexture(textureUrl, textureStretch, textureScale) {
let uuid = this.getUuid();
this.floorplan.setFloorTexture(uuid, textureUrl, textureScale);
this.dispatchEvent({ type: EVENT_CHANGED, item: this });
// this.floorChangeCallbacks.fire();
}
setRoomWallsTextureMaps(texturePack) {
let edge = this.edgePointer;
let iterateWhile = true;
if (!texturePack.color) {
texturePack.color = '#FFFFFF';
}
if (!texturePack.repeat) {
texturePack.repeat = TEXTURE_DEFAULT_REPEAT; //For every TEXTURE_DEFAULT_REPEAT cms
}
edge.setTextureMaps(texturePack);
while (iterateWhile) {
if (edge.next === this.edgePointer) {
break;
} else {
edge = edge.next;
}
edge.setTextureMaps(texturePack);
}
}
setRoomWallsTextureMapsAttribute(attribute, value) {
let edge = this.edgePointer;
let iterateWhile = true;
edge.setTextureMapAttribute(attribute, value);
while (iterateWhile) {
if (edge.next === this.edgePointer) {
break;
} else {
edge = edge.next;
}
edge.setTextureMapAttribute(attribute, value);
}
}
setTextureMaps(texturePack) {
let uuid = this.getUuid();
if (!texturePack.color) {
texturePack.color = '#FFFFFF';
}
if (!texturePack.repeat) {
texturePack.repeat = TEXTURE_DEFAULT_REPEAT; //For every TEXTURE_DEFAULT_REPEAT cms
}
this.floorplan.setFloorTexture(uuid, texturePack);
this.dispatchEvent({ type: EVENT_UPDATE_TEXTURES, item: this });
}
setTextureMapAttribute(attribute, value) {
if (attribute && value) {
let uuid = this.getUuid();
let texturePack = this.getTexture();
texturePack[attribute] = value;
this.floorplan.setFloorTexture(uuid, texturePack);
this.dispatchEvent({ type: EVENT_MODIFY_TEXTURE_ATTRIBUTE, item: this, attribute: attribute, value: value });
}
}
getTexture() {
let uuid = this.getUuid();
let tex = this.floorplan.getFloorTexture(uuid);
if (!tex) {
this.floorplan.setFloorTexture(uuid, defaultFloorTexture);
}
return tex || defaultFloorTexture;
}
generateRoofPlane() {
// setup texture
let geometry = new Geometry();
this.corners.forEach((corner) => {
let vertex = new Vector3(corner.location.x, corner.elevation, corner.location.y);
geometry.vertices.push(vertex);
});
for (let i = 2; i < geometry.vertices.length; i++) {
let face = new Face3(0, i - 1, i);
geometry.faces.push(face);
}
// geometry.computeBoundingBox();
// geometry.computeFaceNormals();
if (!this.roofPlane) {
let buffGeometry = new BufferGeometry().fromGeometry(geometry);
this.roofPlane = new Mesh(buffGeometry, new MeshBasicMaterial({ side: DoubleSide, visible: false }));
} else {
this.roofPlane.geometry.dispose();
this.roofPlane.geometry = new BufferGeometry().fromGeometry(geometry); //this.roofPlane.geometry.fromGeometry(geometry);
}
this.roofPlane.geometry.computeBoundingBox();
this.roofPlane.geometry.computeFaceNormals();
this.roofPlane.room = this;
}
generateFloorPlane() {
let points = [];
this.interiorCorners.forEach((corner) => {
points.push(new Vector2(corner.x, corner.y));
});
let shape = new Shape(points);
let geometry = new ShapeGeometry(shape);
if (!this.floorPlane) {
let buffGeometry = new BufferGeometry().fromGeometry(geometry);
this.floorPlane = new Mesh(buffGeometry, new MeshBasicMaterial({ side: DoubleSide, visible: false }));
} else {
this.floorPlane.geometry.dispose();
this.floorPlane.geometry = new BufferGeometry().fromGeometry(geometry); //this.floorPlane.geometry.fromGeometry(geometry);
}
//The below line was originally setting the plane visibility to false
//Now its setting visibility to true. This is necessary to be detected
//with the raycaster objects to click walls and floors.
this.floorPlane.visible = true;
this.floorPlane.rotation.set(Math.PI / 2, 0, 0);
this.floorPlane.geometry.computeBoundingBox();
this.floorPlane.geometry.computeFaceNormals();
this.floorPlane.room = this; // js monkey patch
let b3 = new Box3();
b3.setFromObject(this.floorPlane);
this.min = b3.min.clone();
this.max = b3.max.clone();
this.center = this.max.clone().sub(this.min).multiplyScalar(0.5).add(this.min);
}
cycleIndex(index) {
if (index < 0) {
return index += this.corners.length;
} else {
return index % this.corners.length;
}
}
pointInRoom(pt) {
let polygon = [];
this.corners.forEach((corner) => {
let co = new Vector2(corner.x, corner.y);
polygon.push(co);
});
return Utils.pointInPolygon2(pt, polygon);
}
updateInteriorCorners() {
let minB = new Vector2(Number.MAX_VALUE, Number.MAX_VALUE);
let maxB = new Vector2(-Number.MAX_VALUE, -Number.MAX_VALUE);
let edge = this.edgePointer;
let iterateWhile = true;
this.interiorCorners = [];
this.interiorCorners3D = [];
while (iterateWhile) {
let iStart = edge.interiorStart();
let cStart = edge.getStart();
minB.x = Math.min(iStart.x, minB.x);
minB.y = Math.min(iStart.y, minB.y);
maxB.x = Math.max(maxB.x, iStart.x);
maxB.y = Math.max(maxB.y, iStart.y);
this.interiorCorners.push(iStart);
this.interiorCorners3D.push(new Vector3(iStart.x, cStart.elevation, iStart.y));
edge.generatePlane();
if (edge.next === this.edgePointer) {
break;
} else {
edge = edge.next;
}
}
this.floorRectangleSize = maxB.clone().sub(minB);
}
updateArea() {
let oldarea = this.area;
let points = [];
let allpoints = [];
this.areaCenter = new Vector2();
this._polygonPoints = [];
let firstCorner, secondCorner, wall, i, corner, region;
for (i = 0; i < this.corners.length; i++) {
corner = this.corners[i];
firstCorner = this.corners[i];
secondCorner = this.corners[(i + 1) % this.corners.length];
wall = firstCorner.wallToOrFrom(secondCorner);
if (wall != null) {
if (wall.wallType === WallTypes.CURVED) {
let begin = corner.location.clone().sub(wall.bezier.get(0)).length();
let p;
let stepIndex;
allpoints.push(corner.location.clone());
if (begin < 1e-6) {
for (stepIndex = 1; stepIndex < 20; stepIndex++) {
p = wall.bezier.get(stepIndex / 20);
allpoints.push(new Vector2(p.x, p.y));
}
} else {
for (stepIndex = 19; stepIndex > 0; stepIndex--) {
p = wall.bezier.get(stepIndex / 20);
allpoints.push(new Vector2(p.x, p.y));
}
}
} else {
allpoints.push(corner.location.clone());
}
} else {
allpoints.push(corner.location.clone());
}
}
points = allpoints;
region = new Region(points);
this.area = Math.abs(region.area());
this.areaCenter = region.centroid();
this._polygonPoints = points;
//Update the planes for intersection purposes
this.generateFloorPlane();
this.generateRoofPlane();
this.dispatchEvent({ type: EVENT_ROOM_ATTRIBUTES_CHANGED, item: this, info: { from: oldarea, to: this.area } });
}
updateArea2() {
let scope = this;
let isComplexRoom = false;
let oldarea = this.area;
let points = [];
let N = 0;
let area = 0;
this.areaCenter = new Vector2();
this._polygonPoints = [];
//The below makes this routine too slow
// this.updateWalls();
// this.updateInteriorCorners();
// this.generateFloorPlane();
// this.generateRoofPlane();
for (let i = 0; i < this.corners.length; i++) {
let firstCorner = this.corners[i];
let secondCorner = this.corners[(i + 1) % this.corners.length];
let wall = firstCorner.wallToOrFrom(secondCorner);
isComplexRoom || (wall.wallType === WallTypes.CURVED);
}
let inext, a, b, ax_by, ay_bx, delta;
if (!isComplexRoom) {
this.corners.forEach((corner) => {
let co = new Vector2(corner.x, corner.y);
scope.areaCenter.add(co);
points.push(co);
});
this.areaCenter.multiplyScalar(1.0 / points.length);
for (let i = 0; i < points.length; i++) {
inext = (i + 1) % points.length;
a = points[i];
b = points[inext];
ax_by = (a.x * b.y);
ay_bx = (a.y * b.x);
delta = ax_by - ay_bx;
area += delta;
}
this.area = Math.abs(area) * 0.5;
this._polygonPoints = points;
this.dispatchEvent({ type: EVENT_ROOM_ATTRIBUTES_CHANGED, item: this, info: { from: oldarea, to: this.area } });
return;
}
// this.corners.forEach((corner) => {
// var co = new Vector2(corner.x,corner.y);
// this.areaCenter.add(co);
// points.push(co);
// });
N = this.corners.length;
for (let i = 0; i < this.corners.length; i++) {
let firstCorner = this.corners[i];
let secondCorner = this.corners[(i + 1) % this.corners.length];
let wall = firstCorner.wallToOrFrom(secondCorner);
this.areaCenter.add(firstCorner.location);
if (wall != null) {
if (wall.wallType === WallTypes.CURVED) {
points.push(firstCorner.location);
let LUT = wall.bezier.getLUT(20);
for (let j = 1; j < LUT.length - 1; j++) {
let p = LUT[j];
p = new Vector2(p.x, p.y);
points.push(p);
}
} else {
points.push(firstCorner.location);
}
} else {
points.push(firstCorner.location);
}
}
this.areaCenter.multiplyScalar(1.0 / N);
let indicesAndAngles = Utils.getCyclicOrder(points, this.areaCenter);
points = indicesAndAngles['points'];
for (let i = 0; i < points.length; i++) {
inext = (i + 1) % points.length;
a = points[i];
b = points[inext];
//Another irregular polygon method based on the url below
//https://www.mathsisfun.com/geometry/area-irregular-polygons.html
// var width = a.x - b.x;
// var height = (a.y + b.y) * 0.5;
// var delta = Math.abs(width * height);
ax_by = (a.x * b.y);
ay_bx = (a.y * b.x);
delta = ax_by - ay_bx;
area += delta;
}
this._polygonPoints = points;
this.area = Math.abs(area) * 0.5;
// if we are using the method in url https://www.mathsisfun.com/geometry/area-irregular-polygons.html
// then we dont have to multiply the area by 0.5;
// this.area = Math.abs(area);
this.dispatchEvent({ type: EVENT_ROOM_ATTRIBUTES_CHANGED, item: this, info: { from: oldarea, to: this.area } });
}
hasAllCornersById(ids) {
let sum = 0;
for (let i = 0; i < ids.length; i++) {
sum += this.hasACornerById(ids[i]);
}
return (sum === this.corners.length);
}
hasACornerById(id) {
for (let i = 0; i < this.corners.length; i++) {
let corner = this.corners[i];
if (corner.id === id) {
return 1;
}
}
return 0;
}
/**
* Populates each wall's half edge relating to this room
* this creates a fancy doubly connected edge list (DCEL)
*/
updateWalls() {
let prevEdge = null;
let firstEdge = null;
this.__walls = [];
for (let i = 0; i < this.corners.length; i++) {
let firstCorner = this.corners[i];
let secondCorner = this.corners[(i + 1) % this.corners.length];
// find if wall is heading in that direction
let wallTo = firstCorner.wallTo(secondCorner);
let wallFrom = firstCorner.wallFrom(secondCorner);
let edge = null;
if (wallTo) {
edge = new HalfEdge(this, wallTo, true);
} else if (wallFrom) {
edge = new HalfEdge(this, wallFrom, false);
} else {
// something horrible has happened
console.log('corners arent connected by a wall, uh oh');
}
/**
* Ensure the room contains the list of wall pointers
*/
if (!this.__walls.includes(wallTo) && wallTo) {
this.__walls.push(wallTo);
wallTo.addRoom(this);
}
if (!this.__walls.includes(wallFrom) && wallFrom) {
this.__walls.push(wallFrom);
wallFrom.addRoom(this);
}
if (i === 0) {
firstEdge = edge;
} else {
edge.prev = prevEdge;
prevEdge.next = edge;
if (i + 1 === this.corners.length) {
firstEdge.prev = edge;
edge.next = firstEdge;
}
}
prevEdge = edge;
}
// hold on to an edge reference
this.edgePointer = firstEdge;
}
set isLocked(flag) {
this.__isLocked = flag;
}
get isLocked() {
return this.__isLocked;
}
get uuid() {
return this.getUuid();
}
get corners() {
return this._corners;
}
get sharedWalls() {
return this.__walls;
}
get roomCornerPoints() {
return this._polygonPoints;
}
get roomByCornersId() {
return this._roomByCornersId;
}
set name(value) {
let oldname = this._name;
this._name = value;
this.dispatchEvent({ type: EVENT_ROOM_ATTRIBUTES_CHANGED, item: this, info: { from: oldname, to: this._name } });
}
get name() {
return this._name;
}
}

743
src/blueprint/scripts/model/wall.ts

@ -0,0 +1,743 @@
import { Bezier } from 'bezier-js';
import { WallTypes, defaultWallTexture } from '../core/constants';
import { Configuration, configWallThickness, configWallHeight } from '../core/configuration';
import { Utils } from '../core/utils.js';
import { InWallItem } from '../items/in_wall_item';
import { InWallFloorItem } from '../items/in_wall_floor_item';
import { WallItem } from '../items/wall_item';
import { WallFloorItem } from '../items/wall_floor_item';
import { Corner } from './corner';
import { Plane, Vector2, Vector3 } from 'babylonjs';
import { EventSystem } from '../core/EventSystem';
/** The default wall texture. */
// export const defaultWallTexture = { url: 'rooms/textures/wallmap.png', stretch: true, scale: 0 };
const UP_VECTOR = new Vector3(0, 0, 1);
/**
* A Wall is the basic element to create Rooms.
*
* Walls consists of two half edges.
*/
export class Wall {
start: Corner;
end: Corner;
name: string;
_walltype: WallTypes;
_a: Vector2;
_b: Vector2;
_a_vector: Vector2;
_b_vector: Vector2;
_bezier: Bezier;
id: string;
/** Front is the plane from start to end. */
__frontEdge = null;
/** Back is the plane from end to start. */
__backEdge = null;
__attachedRooms = [];
/** */
orphan = false;
/** Items attached to this wall */
items = [];
/** */
onItems = [];
__onWallItems = [];
__inWallItems = [];
__onWallItemsSnappedRatios = [];
__inWallItemsSnappedRatios = [];
/** The front-side texture. */
frontTexture = defaultWallTexture;
/** The back-side texture. */
backTexture = defaultWallTexture;
/** Wall thickness. */
_thickness = Configuration.getNumericValue(configWallThickness);
/** Wall height. */
height = Configuration.getNumericValue(configWallHeight);
/** Actions to be applied after movement. */
moved_callbacks = null;
/** Actions to be applied on removal. */
deleted_callbacks = null;
/** Actions to be applied explicitly. */
action_callbacks = null;
__isLocked = false;
__location = new Vector2();
__wallPlane2D;
__wallNormal2D = new Vector2();
__cornerMovedEvent;
__cornerAttributesChangedEvent;
__cornerDeletedEvent;
constructor(start: Corner, end: Corner, aa, bb) {
this.start = start;
this.end = end;
this.name = 'wall';
if (!aa && !bb) {
this._walltype = WallTypes.STRAIGHT;
} else {
this._walltype = WallTypes.CURVED;
}
let o = new Vector2(0, 0);
let abvector = end.location.clone().sub(start.location).multiplyScalar(0.5);
let ab135plus = abvector.clone().rotateAround(o, Math.PI * 0.75);
let ab45plus = abvector.clone().rotateAround(o, Math.PI * 0.25);
if (aa) {
this._a = new Vector2(0, 0);
this._a.x = aa.x;
this._a.y = aa.y;
} else {
this._a = start.location.clone().add(ab45plus);
}
if (bb) {
this._b = new Vector2(0, 0);
this._b.x = bb.x;
this._b.y = bb.y;
} else {
this._b = end.location.clone().add(ab135plus);
}
this._a_vector = this._a.clone().subtract(start.location);
this._b_vector = this._b.clone().subtract(start.location);
this._bezier = new Bezier(start.location.x, start.location.y, this._a.x, this._a.y, this._b.x, this._b.y, end.location.x, end.location.y);
this.id = this.getUuid();
this.start.attachStart(this);
this.end.attachEnd(this);
/** Front is the plane from start to end. */
this.__frontEdge = null;
/** Back is the plane from end to start. */
this.__backEdge = null;
this.__attachedRooms = [];
/** */
this.orphan = false;
/** Items attached to this wall */
this.items = [];
/** */
this.onItems = [];
this.__onWallItems = [];
this.__inWallItems = [];
this.__onWallItemsSnappedRatios = [];
this.__inWallItemsSnappedRatios = [];
/** The front-side texture. */
this.frontTexture = defaultWallTexture;
/** The back-side texture. */
this.backTexture = defaultWallTexture;
/** Wall thickness. */
this._thickness = Configuration.getNumericValue(configWallThickness);
/** Wall height. */
this.height = Configuration.getNumericValue(configWallHeight);
/** Actions to be applied after movement. */
this.moved_callbacks = null;
/** Actions to be applied on removal. */
this.deleted_callbacks = null;
/** Actions to be applied explicitly. */
this.action_callbacks = null;
this.__isLocked = false;
this.__location = new Vector2();
this.__wallPlane2D = new Plane(1, 0, 0, 0);
this.__wallNormal2D = new Vector2();
this.__cornerMovedEvent = this.__cornerMoved.bind(this);
this.__cornerAttributesChangedEvent = this.__cornerAttributesChanged.bind(this);
this.__cornerDeletedEvent = this.__cornerDeleted.bind(this);
// this.start.addEventListener(EVENT_MOVED, () => {
// scope.updateControlVectors();
// });
// this.end.addEventListener(EVENT_MOVED, () => {
// scope.updateControlVectors();
// });
this.addCornerMoveListener(this.start);
this.addCornerMoveListener(this.end);
}
__updateItemPositions() {
let i = 0;
let vect = this.end.location.clone().sub(this.start.location);
this.__onWallItems.forEach((item) => {
let snappedRatio = this.__onWallItemsSnappedRatios[i];
let newPosition = vect.clone().multiplyScalar(snappedRatio).add(this.start.location);
item.position = new Vector3(newPosition.x, item.position.y, newPosition.y);
i++;
});
i = 0;
this.__inWallItems.forEach((item) => {
let snappedRatio = this.__inWallItemsSnappedRatios[i];
let newPosition = vect.clone().multiplyScalar(snappedRatio).add(this.start.location);
item.position = new Vector3(newPosition.x, item.position.y, newPosition.y);
i++;
});
}
__cornerMoved() {
this.updateControlVectors();
// this.dispatchEvent({ type: EVENT_MOVED, item: this, position: null });
EventSystem.Instance.sendMessage("MOVED_EVENT", this);
}
__cornerAttributesChanged() {
this.__updateItemPositions();
// this.dispatchEvent({ type: EVENT_MOVED, item: this, position: null });
EventSystem.Instance.sendMessage("MOVED_EVENT", this);
}
__cornerDeleted(evt) {
this.addCornerMoveListener(evt.item, true);
this.remove();
}
addItem(item) {
if (item instanceof InWallItem || item instanceof InWallFloorItem) {
if (!Utils.hasValue(this.__inWallItems, item)) {
this.__inWallItems.push(item);
}
// this.dispatchEvent({ type: EVENT_MOVED, item: this, position: null });
EventSystem.Instance.sendMessage("MOVED_EVENT", this);
}
if (item instanceof WallItem || item instanceof WallFloorItem) {
if (!Utils.hasValue(this.__onWallItems, item)) {
this.__onWallItems.push(item);
}
// this.dispatchEvent({ type: EVENT_MOVED, item: this, position: null });
EventSystem.Instance.sendMessage("MOVED_EVENT", this);
}
}
removeItem(item) {
if (item instanceof InWallItem || item instanceof InWallFloorItem) {
if (Utils.hasValue(this.__inWallItems, item)) {
Utils.removeValue(this.__inWallItems, item);
}
// this.dispatchEvent({ type: EVENT_MOVED, item: this, position: null });
EventSystem.Instance.sendMessage("MOVED_EVENT", this);
}
if (item instanceof WallItem || item instanceof WallFloorItem) {
if (Utils.hasValue(this.__onWallItems, item)) {
Utils.removeValue(this.__onWallItems, item);
}
// this.dispatchEvent({ type: EVENT_MOVED, item: this, position: null });
EventSystem.Instance.sendMessage("MOVED_EVENT", this);
}
}
addCornerMoveListener(corner, remove = false) {
// if (remove) {
// corner.removeEventListener(EVENT_MOVED, this.__cornerMovedEvent);
// corner.removeEventListener(EVENT_CORNER_ATTRIBUTES_CHANGED, this.__cornerAttributesChangedEvent);
// corner.removeEventListener(EVENT_DELETED, this.__cornerDeletedEvent);
// return;
// }
// corner.addEventListener(EVENT_MOVED, this.__cornerMovedEvent);
// corner.addEventListener(EVENT_CORNER_ATTRIBUTES_CHANGED, this.__cornerAttributesChangedEvent);
// corner.addEventListener(EVENT_DELETED, this.__cornerDeletedEvent);
}
projectOnWallPlane(pt2d) {
let projected3D = new Vector3();
projected3D = this.__wallPlane2D.projectPoint(new Vector3(pt2d.x, pt2d.y, 0), projected3D);
return new Vector2(projected3D.x, projected3D.y);
}
updateControlVectors() {
//Update the location as a mid point between two corners
let s = this.start.location.clone();
let e = this.end.location.clone();
let vect = e.clone().sub(s.clone());
let halfVect = vect.clone().multiplyScalar(0.5);
let midPoint = s.clone().add(halfVect);
this.__location = midPoint.clone();
//Update the wall plane in a 2D sense
let vect3d = new Vector3(vect.x, vect.y, 0);
let normal = vect3d.clone().normalize().cross(UP_VECTOR);
this.__wallPlane2D = this.__wallPlane2D.setFromNormalAndCoplanarPoint(normal, new Vector3(midPoint.x, midPoint.y, 0));
this.__wallNormal2D.x = vect3d.x;
this.__wallNormal2D.y = vect3d.y;
// console.log(this.__wallPlane2D.normal, this.__wallPlane2D.constant);
this._bezier.points[0].x = this.start.location.x;
this._bezier.points[0].y = this.start.location.y;
this._bezier.points[1].x = this.a.x;
this._bezier.points[1].y = this.a.y;
this._bezier.points[2].x = this.b.x;
this._bezier.points[2].y = this.b.y;
this._bezier.points[3].x = this.end.location.x;
this._bezier.points[3].y = this.end.location.y;
this._bezier.update();
if (this.getStart() || this.getEnd()) {
(this.getStart() != null) ? this.getStart().floorplan.update(false) : (this.getEnd() != null) ? this.getEnd().floorplan.update(false) : false;
}
// this._a_vector = this._a.clone().sub(this.start.location);
// this._b_vector = this._b.clone().sub(this.start.location);
}
getUuid() {
return [this.start.id, this.end.id].join();
}
resetFrontBack() {
if (this.frontEdge) {
this.frontEdge.destroy();
}
if (this.backEdge) {
this.backEdge.destroy();
}
this.frontEdge = null;
this.backEdge = null;
this.orphan = false;
this.__attachedRooms = [];
}
snapToAxis(tolerance) {
// order here is important, but unfortunately arbitrary
this.start.snapToAxis(tolerance);
this.end.snapToAxis(tolerance);
}
fireOnMove(func) {
this.moved_callbacks.add(func);
}
fireOnDelete(func) {
this.deleted_callbacks.add(func);
}
dontFireOnDelete(func) {
this.deleted_callbacks.remove(func);
}
fireOnAction(func) {
this.action_callbacks.add(func);
}
fireAction(action) {
this.dispatchEvent({ type: EVENT_ACTION, action: action });
//this.action_callbacks.fire(action);
}
move(newX, newY) {
let dx = newX - ((this.start.location.x + this.end.location.x) * 0.5);
let dy = newY - ((this.start.location.y + this.end.location.y) * 0.5);
this.relativeMove(dx, dy);
}
relativeMove(dx, dy, corner) {
if (!corner) {
this.start.relativeMove(dx, dy);
this.end.relativeMove(dx, dy);
} else {
corner.relativeMove(dx, dy);
}
this.updateControlVectors();
}
fireMoved() {
this.dispatchEvent({ type: EVENT_MOVED, item: this, position: null });
}
fireRedraw() {
if (this.frontEdge) {
// this.frontEdge.dispatchEvent({type: EVENT_REDRAW});
this.frontEdge.dispatchRedrawEvent();
//this.frontEdge.redrawCallbacks.fire();
}
if (this.backEdge) {
// this.backEdge.dispatchEvent({type: EVENT_REDRAW});
this.backEdge.dispatchRedrawEvent();
//this.backEdge.redrawCallbacks.fire();
}
}
set isLocked(flag) {
this.__isLocked = flag;
}
get isLocked() {
return this.__isLocked;
}
set wallSize(value) {
if (this.wallType === WallTypes.STRAIGHT) {
let vector = this.getEnd().location.clone().sub(this.getStart().location);
let currentLength = this.wallLength();
let changeInLength = value / currentLength;
let neighboursCountStart = (this.getStart().adjacentCorners().length === 1);
let neighboursCountEnd = (this.getEnd().adjacentCorners().length === 1);
let changeInLengthOffset, movementVector, startPoint, endPoint;
changeInLengthOffset = (changeInLength - 1);
if ((!neighboursCountStart && !neighboursCountEnd) || (neighboursCountStart && neighboursCountEnd)) {
changeInLengthOffset *= 0.5;
movementVector = vector.clone().multiplyScalar(changeInLengthOffset);
startPoint = movementVector.clone().multiplyScalar(-1).add(this.getStart().location);
endPoint = movementVector.clone().add(this.getEnd().location);
} else if (neighboursCountStart) {
movementVector = vector.clone().multiplyScalar(changeInLengthOffset);
startPoint = movementVector.clone().multiplyScalar(-1).add(this.getStart().location);
endPoint = this.getEnd().location;
} else if (neighboursCountEnd) {
movementVector = vector.clone().multiplyScalar(changeInLengthOffset);
endPoint = movementVector.clone().add(this.getEnd().location);
startPoint = this.getStart().location;
}
this.getStart().move(startPoint.x, startPoint.y);
this.getEnd().move(endPoint.x, endPoint.y);
this.updateAttachedRooms();
// vector = vector.multiplyScalar(changeInLength).add(this.getStart().location);
// this.getEnd().move(vector.x, vector.y);
}
/**
* No need for the below statement. Because the corners moved will trigger the event to this instance
* Then this instance will also trigger the move event
*/
// this.dispatchEvent({ type: EVENT_UPDATED, item: this });
}
get onWallItems() {
return this.__onWallItems;
}
get inWallItems() {
return this.__inWallItems;
}
get attachedRooms() {
return this.__attachedRooms;
}
get thickness() {
return this._thickness;
}
set thickness(thick) {
this._thickness = thick;
this.start.move(this.start.location.x, this.start.location.y);
this.end.move(this.end.location.x, this.end.location.y);
// this.dispatchEvent({ type: EVENT_UPDATED, item: this }); //This is stupid. You need to say what event exactly happened
}
get uuid() {
return this.getUuid();
}
get a() {
return this._a;
}
set a(location) {
this._a.x = location.x;
this._a.y = location.y;
this._a_vector = this._a.clone().sub(this.start.location);
this.updateControlVectors();
}
get b() {
return this._b;
}
set b(location) {
this._b.x = location.x;
this._b.y = location.y;
this._b_vector = this._b.clone().sub(this.start.location);
this.updateControlVectors();
}
get aVector() {
return this._a_vector.clone();
}
get bVector() {
return this._b_vector.clone();
}
get bezier() {
return this._bezier;
}
get wallSize() {
return this.wallLength();
}
get wallType() {
return this._walltype;
}
set wallType(value) {
if (value === WallTypes.STRAIGHT || value === WallTypes.CURVED) {
this._walltype = value;
}
this.updateControlVectors();
this.updateAttachedRooms(true);
}
get startElevation() {
if (this.start && this.start != null) {
return this.start.elevation;
}
return 0.0;
}
get endElevation() {
if (this.end && this.end != null) {
return this.end.elevation;
}
return 0.0;
}
get location() {
return this.__location;
}
set location(vec2) {
let s = this.start.location.clone();
let e = this.end.location.clone();
let vect = e.clone().sub(s);
let midPoint = s.clone().add(vect.clone().multiplyScalar(0.5));
let vectorSToMid = s.clone().sub(midPoint);
let vectorEToMid = e.clone().sub(midPoint);
let sNewLocation = vec2.clone().add(vectorSToMid);
let eNewLocation = vec2.clone().add(vectorEToMid);
this.start.move(sNewLocation.x, sNewLocation.y);
this.end.move(eNewLocation.x, eNewLocation.y);
this.__location = vec2;
}
getStart() {
return this.start;
}
getEnd() {
return this.end;
}
getStartX() {
return this.start.getX();
}
getEndX() {
return this.end.getX();
}
getStartY() {
return this.start.getY();
}
getEndY() {
return this.end.getY();
}
wallDirection() {
let vector = this.end.location.clone().sub(this.start.location);
return vector;
}
wallDirectionNormalized() {
return this.wallDirection().normalize();
}
wallDirection3() {
let wd = this.wallDirection();
return new Vector3(wd.x, wd.y, 0);
}
wallDirectionNormalized3() {
let wd3 = this.wallDirection3();
return wd3.normalize();
}
wallLength() {
if (this.wallType === WallTypes.STRAIGHT) {
let start = this.getStart();
let end = this.getEnd();
return Utils.distance(start, end);
} else if (this.wallType === WallTypes.CURVED) {
return this._bezier.length();
}
return -1;
}
wallCenter() {
if (this.wallType === WallTypes.STRAIGHT) {
return new Vector2((this.getStart().x + this.getEnd().x) / 2.0, (this.getStart().y + this.getEnd().y) / 2.0);
} else if (this.wallType === WallTypes.CURVED) {
let p = this._bezier.get(0.5);
return new Vector2(p.x, p.y);
}
return new Vector2(0, 0);
}
remove() {
this.start.detachWall(this);
this.end.detachWall(this);
//Remove the listeners also
this.addCornerMoveListener(this.start, true);
this.addCornerMoveListener(this.end, true);
this.dispatchEvent({ type: EVENT_DELETED, item: this });
//this.deleted_callbacks.fire(this);
}
setStart(corner) {
this.start.detachWall(this);
this.addCornerMoveListener(this.start, true);
corner.attachStart(this);
this.start = corner;
this.addCornerMoveListener(this.start);
this.fireMoved();
}
setEnd(corner) {
this.end.detachWall(this);
this.addCornerMoveListener(this.end);
corner.attachEnd(this);
this.end = corner;
this.addCornerMoveListener(this.end, true);
this.fireMoved();
}
distanceFrom(point) {
if (this.wallType === WallTypes.STRAIGHT) {
return Utils.pointDistanceFromLine(point, new Vector2(this.getStartX(), this.getStartY()), new Vector2(this.getEndX(), this.getEndY()));
} else if (this.wallType === WallTypes.CURVED) {
let p = this._bezier.project(point);
let projected = new Vector2(p.x, p.y);
return projected.distanceTo(point);
}
return -1;
}
/** Return the corner opposite of the one provided.
* @param corner The given corner.
* @returns The opposite corner.
*/
oppositeCorner(corner) {
if (this.start === corner) {
return this.end;
} else if (this.end === corner) {
return this.start;
} else {
console.log('Wall does not connect to corner');
return null;
}
}
getClosestCorner(point) {
let startVector = new Vector2(this.start.x, this.start.y);
let endVector = new Vector2(this.end.x, this.end.y);
let startDistance = point.distanceTo(startVector);
let endDistance = point.distanceTo(endVector);
if (startDistance <= (this.thickness * 2)) {
return this.start;
} else if (endDistance <= (this.thickness * 2)) {
return this.end;
}
return null;
}
updateAttachedRooms(explicit = false) {
if (this.start != null) {
this.start.updateAttachedRooms(explicit);
}
if (this.end) {
this.end.updateAttachedRooms(explicit);
}
}
addRoom(room) {
this.__attachedRooms.push(room);
}
clearAttachedRooms() {
this.__attachedRooms = [];
}
get frontEdge() {
return this.__frontEdge;
}
set frontEdge(edge) {
if (this.__frontEdge) {
this.__frontEdge.destroy();
}
this.__frontEdge = edge;
this.__inWallItems.forEach((item) => {
item.newWallEdge();
});
this.__onWallItems.forEach((item) => {
item.newWallEdge();
});
this.dispatchEvent({ type: EVENT_UPDATED, item: this });
}
get backEdge() {
return this.__backEdge;
}
set backEdge(edge) {
if (this.__backEdge) {
this.__backEdge.destroy();
}
this.__backEdge = edge;
this.__inWallItems.forEach((item) => {
item.newWallEdge();
});
this.__onWallItems.forEach((item) => {
item.newWallEdge();
});
this.dispatchEvent({ type: EVENT_UPDATED, item: this });
}
}
export default Wall;

0
src/blueprint/scripts/page-not-found/page-not-found.component.css

123
src/blueprint/scripts/page-not-found/page-not-found.component.html

@ -0,0 +1,123 @@
<!DOCTYPE html>
<html>
<head>
<title>Flip Jump</title>
<link rel="icon" type="image/x-icon" href="/media/graphics/misc/favicon.ico" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<meta name="viewport"
content="initial-scale=1.0001, minimum-scale=1.0001, maximum-scale=1.0001, user-scalable=no, minimal-ui" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<!-- <link rel="stylesheet" type="text/css" href="game.css"> -->
<!-- <script type="text/javascript" src="game.js"></script> -->
</head>
<body onload="setTimeout(function(){window.scrollTo(0,1)},1);">
<div id="ajaxbar">
<div id="game"><canvas id="canvas"></canvas></div>
<div id="webgl"><canvas id="webglcanvas"></canvas></div>
<div id="orientate"><img src="media/graphics/orientate/landscape.jpg" /></div>
<div id="play" class="play" onclick=""><img src="media/graphics/splash/mobile/cover-start.jpg" /></div>
<div id="MobileAdInGamePreroll">
<div id="MobileAdInGamePreroll-Box">
<div id="MobileAdInGamePreroll-Box-Header"></div>
<a id="MobileAdInGamePreroll-Box-Close" onclick="MobileAdInGamePreroll.Close();"></a>
<div id="MobileAdInGamePreroll-Box-Body">
<img src="https://cdn-factory.marketjs.com/generic.png">
</div>
<div id='MobileAdInGamePreroll-Box-Footer'></div>
</div>
</div>
<div id="MobileAdInGamePreroll2">
<div id="MobileAdInGamePreroll2-Box">
<div id="MobileAdInGamePreroll2-Box-Header"></div>
<a id="MobileAdInGamePreroll2-Box-Close" onclick="MobileAdInGamePreroll.Close();"></a>
<div id="MobileAdInGamePreroll2-Box-Body">
</div>
<div id='MobileAdInGamePreroll2-Box-Footer'></div>
</div>
</div>
<div id="MobileAdInGamePreroll3">
<div id="MobileAdInGamePreroll3-Box">
<div id="MobileAdInGamePreroll3-Box-Header"></div>
<a id="MobileAdInGamePreroll3-Box-Close" onclick="MobileAdInGamePreroll.Close();"></a>
<div id="MobileAdInGamePreroll3-Box-Body">
</div>
<div id='MobileAdInGamePreroll3-Box-Footer'></div>
</div>
</div>
<div id="MobileAdInGameHeader">
</div>
<div id="MobileAdInGameHeader2">
</div>
<div id="MobileAdInGameHeader3">
</div>
<div id="MobileAdInGameFooter">
</div>
<div id="MobileAdInGameFooter2">
</div>
<div id="MobileAdInGameFooter3">
</div>
<div id="MobileAdInGameEnd">
<div id="MobileAdInGameEnd-Box">
<div id="MobileAdInGameEnd-Box-Header"></div>
<a id="MobileAdInGameEnd-Box-Close" onclick="MobileAdInGameEnd.Close();"></a>
<div id="MobileAdInGameEnd-Box-Body">
</div>
<div id='MobileAdInGameEnd-Box-Footer'></div>
</div>
</div>
<div id="MobileAdInGameEnd2">
<div id="MobileAdInGameEnd2-Box">
<div id="MobileAdInGameEnd2-Box-Header"></div>
<a id="MobileAdInGameEnd2-Box-Close" onclick="MobileAdInGameEnd.Close();"></a>
<div id="MobileAdInGameEnd2-Box-Body">
</div>
<div id='MobileAdInGameEnd2-Box-Footer'></div>
</div>
</div>
<div id="MobileAdInGameEnd3">
<div id="MobileAdInGameEnd3-Box">
<div id="MobileAdInGameEnd3-Box-Header"></div>
<a id="MobileAdInGameEnd3-Box-Close" onclick="MobileAdInGameEnd.Close();"></a>
<div id="MobileAdInGameEnd3-Box-Body">
</div>
<div id='MobileAdInGameEnd3-Box-Footer'></div>
</div>
</div>
</div>
</body>
</html>

25
src/blueprint/scripts/page-not-found/page-not-found.component.spec.ts

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PageNotFoundComponent } from './page-not-found.component';
describe('PageNotFoundComponent', () => {
let component: PageNotFoundComponent;
let fixture: ComponentFixture<PageNotFoundComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageNotFoundComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PageNotFoundComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

15
src/blueprint/scripts/page-not-found/page-not-found.component.ts

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-page-not-found',
templateUrl: './page-not-found.component.html',
styleUrls: ['./page-not-found.component.css']
})
export class PageNotFoundComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

23
src/blueprint/scripts/parametrics/ParametricFactory.js

@ -0,0 +1,23 @@
import Enum from "es6-enum";
import { DoorFactory } from "./doors/DoorFactory";
export const TYPE_DOOR = "DOOR";
export const TYPE_WINDOW = "WINDOW";
export const TYPE_CABINET = "CABINET";
export const TYPE_SHELVES = "SHELVES";
export const BASE_PARAMETRIC_TYPES = Enum(TYPE_DOOR, TYPE_WINDOW, TYPE_CABINET, TYPE_SHELVES);
export const BASE_PARAMETRIC_OBJECTS = { DOOR: DoorFactory };
/** Factory class to create items. */
export class ParametricFactory {
/** Gets the class for the specified item. */
static getParametricClass(parametricType) {
let parametricClass = BASE_PARAMETRIC_OBJECTS[parametricType];
if (parametricClass !== undefined) {
return parametricClass;
}
throw new Error('Unimplemented parametric class error');
}
}

16
src/blueprint/scripts/parametrics/doors/DoorFactory.js

@ -0,0 +1,16 @@
import { ParametricBaseDoor } from "./ParametricBaseDoor";
import { ParametricDoorType2 } from "./ParametricDoorType2";
import { ParametricDoorType3 } from "./ParametricDoorType3";
import { ParametricDoorType4 } from "./ParametricDoorType4";
import { ParametricDoorType5 } from "./ParametricDoorType5";
import { ParametricDoorType6 } from "./ParametricDoorType6";
export const DOOR_TYPES = { 1: ParametricBaseDoor, 2: ParametricDoorType2, 3: ParametricDoorType3, 4: ParametricDoorType4, 5: ParametricDoorType5, 6: ParametricDoorType6 };
/** Factory class to create items. */
export class DoorFactory {
/** Gets the class for the specified item. */
static getClass(doorType) {
return DOOR_TYPES[doorType];
}
}

531
src/blueprint/scripts/parametrics/doors/ParametricBaseDoor.js

@ -0,0 +1,531 @@
import Enum from "es6-enum";
import { BufferGeometry, Matrix4, Vector3, Face3, Geometry, DoubleSide, Color } from "three";
import { MeshStandardMaterial, EventDispatcher } from "three";
import { EVENT_PARAMETRIC_GEOMETRY_UPATED } from "../../core/events";
import { DoorHandleGenerator } from "./doorhandles/DoorHandleGenerator";
export const DOOR_OPEN_DIRECTIONS = Enum('RIGHT', 'LEFT', 'BOTH_SIDES', 'NO_DOORS');
export const DOOR_HANDLE_TYPES = Enum('None', 'HANDLE_01', 'HANDLE_02', 'HANDLE_03', 'HANDLE_04');
/**
* ParametricBaseDoor is the implementation of Model 01 from Archimesh
*/
export class ParametricBaseDoor extends EventDispatcher {
constructor(parameters) {
super();
let opts = { frameSize: 5, frameColor: '#FF0000', doorColor: '#E0E0EE', frameWidth: 100, frameHeight: 200, frameThickness: 20, doorRatio: 0.5, openDirection: DOOR_OPEN_DIRECTIONS.RIGHT.description, handleType: DOOR_HANDLE_TYPES.HANDLE_01.description, doorHandleColor: '#F0F0F0', glassColor: '#87CEEB' };
for (var opt in opts) {
if (opt === 'frameColor' || opt === 'doorColor' || opt === 'doorHandleColor' || opt === 'glassColor') {
opts[opt] = new Color(parameters[opt]);
} else if (opts.hasOwnProperty(opt) && parameters.hasOwnProperty(opt)) {
opts[opt] = parameters[opt];
}
}
opts = this.__validateParameters(opts);
this.__doorType = 1;
this.__name = 'Door';
this.__frameSize = opts.frameSize; //This value will be set in validatePArameters
this.__frameWidth = opts.frameWidth;
this.__frameHeight = opts.frameHeight;
this.__frameThickness = opts.frameThickness;
this.__doorRatio = opts.doorRatio;
this.__openDirection = null;
this.__handleType = null;
switch (opts.openDirection) {
case DOOR_OPEN_DIRECTIONS.RIGHT.description:
this.__openDirection = DOOR_OPEN_DIRECTIONS.RIGHT; //This value will be set in validatePArameters
break;
case DOOR_OPEN_DIRECTIONS.LEFT.description:
this.__openDirection = DOOR_OPEN_DIRECTIONS.LEFT; //This value will be set in validatePArameters
break;
case DOOR_OPEN_DIRECTIONS.BOTH_SIDES.description:
this.__openDirection = DOOR_OPEN_DIRECTIONS.BOTH_SIDES; //This value will be set in validatePArameters
break;
case DOOR_OPEN_DIRECTIONS.NO_DOORS.description:
this.__openDirection = DOOR_OPEN_DIRECTIONS.NO_DOORS; //This value will be set in validatePArameters
break;
}
switch (opts.handleType) {
case DOOR_HANDLE_TYPES.None.description:
this.__handleType = DOOR_HANDLE_TYPES.None; //This value will be set in validatePArameters
break;
case DOOR_HANDLE_TYPES.HANDLE_01.description:
this.__handleType = DOOR_HANDLE_TYPES.HANDLE_01; //This value will be set in validatePArameters
break;
case DOOR_HANDLE_TYPES.HANDLE_02.description:
this.__handleType = DOOR_HANDLE_TYPES.HANDLE_02; //This value will be set in validatePArameters
break;
case DOOR_HANDLE_TYPES.HANDLE_03.description:
this.__handleType = DOOR_HANDLE_TYPES.HANDLE_03; //This value will be set in validatePArameters
break;
case DOOR_HANDLE_TYPES.HANDLE_04.description:
this.__handleType = DOOR_HANDLE_TYPES.HANDLE_04; //This value will be set in validatePArameters
break;
}
this.__frameMaterial = new MeshStandardMaterial({ color: opts.frameColor, side: DoubleSide });
this.__doorMaterial = new MeshStandardMaterial({ color: opts.doorColor, side: DoubleSide, wireframe: false });
this.__handleMaterial = new MeshStandardMaterial({ color: '#F0F0FF', side: DoubleSide, wireframe: false });
this.__rightDoorMaterial = this.__doorMaterial; //new MeshStandardMaterial({ color: '#FF0000', wireframe: false }); //Right is red color
this.__leftDoorMaterial = this.__doorMaterial; //new MeshStandardMaterial({ color: '#0000FF', wireframe: false }); //Left is blue color
this.__doorHandleMaterial = new MeshStandardMaterial({ color: opts.doorHandleColor, wireframe: false, roughness: 0.0, metalness: 0.0 });
this.__glassMaterial = new MeshStandardMaterial({ color: opts.glassColor, side: DoubleSide, wireframe: false, transparent: true, opacity: 0.6 });
this.__doorFrameMaterialId = 0;
this.__doorMaterialId = 1;
this.__leftDoorMaterialId = 2;
this.__rightDoorMaterialId = 3;
this.__doorHandleMaterialId = 4;
this.__glassMaterialId = 5;
this.__material = [
this.__frameMaterial,
this.__doorMaterial,
this.__leftDoorMaterial,
this.__rightDoorMaterial,
this.__doorHandleMaterial,
this.__glassMaterial
];
this.__doorMaterial.normalScale.set(100, 100, 100);
this.__geometry = this.__proceedure();
}
__convertFrom4ToFace3(facegroups, materialId = 0) {
let faces = [];
for (let i = 0; i < facegroups.length; i += 4) {
let f1 = new Face3(facegroups[i], facegroups[i + 1], facegroups[i + 2]);
let f2 = new Face3(facegroups[i], facegroups[i + 2], facegroups[i + 3]);
f1.materialIndex = materialId;
f2.materialIndex = materialId;
faces.push(f1);
faces.push(f2);
}
return faces;
}
__validateParameters(parameters) {
parameters.frameSize = Math.max(5, Math.min(25, parameters.frameSize)); //Expressed in centimeters
parameters.doorRatio = Math.max(0.0, Math.min(1.0, parameters.doorRatio)); //Expressed in centimeters
let doorOpenParameter = parameters.openDirection;
switch (doorOpenParameter) {
case DOOR_OPEN_DIRECTIONS.RIGHT.description:
case DOOR_OPEN_DIRECTIONS.LEFT.description:
case DOOR_OPEN_DIRECTIONS.BOTH_SIDES.description:
case DOOR_OPEN_DIRECTIONS.NO_DOORS.description:
break;
default:
throw new Error('Unindentifiable door type');
}
return parameters;
}
__updateGeometry() {
let updatedGeometry = this.__proceedure();
this.__geometry.dispose();
this.__geometry = updatedGeometry;
this.dispatchEvent({ type: EVENT_PARAMETRIC_GEOMETRY_UPATED, target: this });
}
__proceedure() {
let returnGeometry = null;
let doorGeometry = new Geometry();
let doorFrameGeometry = this.__shapeMesh();
let doorsToGenerate = this.__shapeChildren();
if (doorFrameGeometry) {
doorGeometry.merge(doorFrameGeometry);
}
if (doorsToGenerate.right) {
doorGeometry.merge(doorsToGenerate.right);
}
if (doorsToGenerate.left) {
doorGeometry.merge(doorsToGenerate.left);
}
doorGeometry.computeVertexNormals();
doorGeometry.computeFaceNormals();
doorGeometry.computeBoundingBox();
returnGeometry = new BufferGeometry().fromGeometry(doorGeometry);
returnGeometry.normalizeNormals();
return returnGeometry;
}
__shapeMesh() {
let doorFrameGeometry = this.__createDoorFrame();
return doorFrameGeometry;
}
__createDoorFrame() {
let tf = this.__frameThickness / 3.0;
let sf = this.__frameSize;
let wf = (this.__frameWidth * 0.5) - sf;
let hf = this.__frameHeight - sf;
let gap = 0.02;
let deep = this.__frameThickness * 0.50;
let verts = [
new Vector3(-wf - sf, -tf, 0),
new Vector3(-wf - sf, tf * 2, 0),
new Vector3(-wf, tf * 2, 0),
new Vector3(-wf - sf, -tf, hf + sf),
new Vector3(-wf - sf, tf * 2, hf + sf),
new Vector3(wf + sf, tf * 2, hf + sf),
new Vector3(wf + sf, -tf, hf + sf),
new Vector3(wf, -tf, hf),
new Vector3(-wf, tf * 2, hf),
new Vector3(wf, -tf, 0),
new Vector3(wf + sf, -tf, 0),
new Vector3(wf + sf, tf * 2, 0),
new Vector3(wf, -tf + deep, hf),
new Vector3(-wf, -tf + deep, hf),
new Vector3(-wf, -tf + deep, 0),
new Vector3(-wf + gap, -tf + deep, hf),
new Vector3(-wf + gap, -tf + deep, 0),
new Vector3(-wf + gap, tf * 2, hf),
new Vector3(-wf + gap, tf * 2, 0),
new Vector3(wf, -tf + deep, 0),
new Vector3(-wf, -tf, hf),
new Vector3(-wf, -tf, 0),
new Vector3(wf, tf * 2, hf),
new Vector3(wf, tf * 2, 0),
new Vector3(wf - gap, tf * 2, 0),
new Vector3(wf - gap, -tf + deep, 0),
new Vector3(wf - gap, tf * 2, hf),
new Vector3(wf - gap, -tf + deep, hf - gap),
new Vector3(wf - gap, -tf + deep, hf),
new Vector3(-wf + gap, tf * 2, hf - gap),
new Vector3(-wf + gap, -tf + deep, hf - gap),
new Vector3(wf - gap, tf * 2, hf - gap)
];
let geometry = new Geometry();
let faceIds = [3, 4, 1, 0, 7, 12, 19, 9, 4, 3, 6, 5, 10, 11, 5, 6, 13, 20, 21, 14, 17, 15, 16, 18, 11, 23, 22, 5, 20, 13, 12, 7, 20, 3, 0, 21, 9, 10, 6, 7, 13, 14, 16, 15, 4, 8, 2, 1, 29, 30, 27, 31, 7, 6, 3, 20, 8, 4, 5, 22, 14, 2, 18, 16, 17, 18, 2, 8, 28, 25, 19, 12, 28, 26, 24, 25, 25, 24, 23, 19, 22, 23, 24, 26, 29, 31, 26, 17, 15, 28, 27, 30];
let faces = this.__convertFrom4ToFace3(faceIds, 0);
let extraFace = new Face3(8, 22, 26);
extraFace.materialIndex = 0;
faces.push(extraFace);
geometry.vertices = verts;
geometry.faces = faces;
geometry.elementsNeedUpdate = true;
geometry.applyMatrix4(new Matrix4().makeRotationAxis(new Vector3(1, 0, 0), -Math.PI * 0.5));
geometry.applyMatrix4(new Matrix4().makeTranslation(0, -this.__frameHeight * 0.5, 0));
geometry.computeVertexNormals();
geometry.computeFaceNormals();
geometry.computeBoundingBox();
return geometry; //new BufferGeometry().fromGeometry(geometry);
}
__shapeChildren() {
let doorRight = null,
doorLeft = null;
let w = this.__frameWidth;
let w1 = (w * this.__doorRatio);
let w2 = (w - w1);
switch (this.__openDirection) {
case DOOR_OPEN_DIRECTIONS.NO_DOORS:
break;
case DOOR_OPEN_DIRECTIONS.LEFT:
//Get the buffergeometry of only one door
doorLeft = this.__makeOneDoor(w, this.__openDirection, this.__leftDoorMaterialId, 'Left');
doorLeft.applyMatrix4(new Matrix4().makeTranslation(-(this.__frameWidth * 0.5) + this.__frameSize, 0, 0));
break;
case DOOR_OPEN_DIRECTIONS.RIGHT:
//Get the buffergeometry of only one door
doorRight = this.__makeOneDoor(w, this.__openDirection, this.__rightDoorMaterialId, 'Right');
doorRight.applyMatrix4(new Matrix4().makeTranslation((this.__frameWidth * 0.5) - this.__frameSize, 0, 0));
break;
case DOOR_OPEN_DIRECTIONS.BOTH_SIDES:
//Get the buffergeometry of left door
doorLeft = this.__makeOneDoor(w1 + this.__frameSize, DOOR_OPEN_DIRECTIONS.LEFT, this.__leftDoorMaterialId, 'Left');
doorLeft.applyMatrix4(new Matrix4().makeTranslation(-(this.__frameWidth * 0.5) + this.__frameSize, 0, 0));
//Get the buffergeometry of right door
doorRight = this.__makeOneDoor(w2 + this.__frameSize, DOOR_OPEN_DIRECTIONS.RIGHT, this.__rightDoorMaterialId, 'Right');
doorRight.applyMatrix4(new Matrix4().makeTranslation((this.__frameWidth * 0.5) - this.__frameSize, 0, 0));
break;
default:
throw new Error(`Unindentifiable door type ${this.__openDirection}`);
}
return { right: doorRight, left: doorLeft };
}
__makeOneDoor(frameWidth, openingDirection, materialId = 1, doorSide = 'Right') {
let aDoorGeometry = this.__createDoorData(frameWidth, openingDirection, materialId);
if (this.__handleType !== DOOR_HANDLE_TYPES.None) {
let doorRatio = (doorSide === 'Right') ? 1.0 - this.doorRatio : this.doorRatio;
let front_handle = DoorHandleGenerator.generate_handle(this.__handleType.description, 'Front', doorSide, doorRatio, this.frameWidth, this.frameSize, this.frameThickness, this.__openDirection.description, this.__doorHandleMaterialId);
let back_handle = DoorHandleGenerator.generate_handle(this.__handleType.description, 'Back', doorSide, doorRatio, this.frameWidth, this.frameSize, this.frameThickness, this.__openDirection.description, this.__doorHandleMaterialId);
aDoorGeometry.merge(front_handle);
aDoorGeometry.merge(back_handle);
}
return aDoorGeometry;
}
__createDoorData(frameWidth, openingDirection, materialId = 1) {
let doorModelData = this.__createForDoorModel(frameWidth, openingDirection, materialId);
let geometry = new Geometry();
let m = new Matrix4();
let tx = (doorModelData.widthFactor * 0.5) * doorModelData.side;
let ty = this.__frameHeight * 0.5;
let tz = -(doorModelData.depth * 0.65);
geometry.vertices = doorModelData.vertices;
geometry.faces = doorModelData.faces;
geometry.elementsNeedUpdate = true;
m.makeRotationAxis(new Vector3(1, 0, 0), -Math.PI * 0.5);
// m.multiply(new Matrix4().makeTranslation(0, tz, ty));
// m.makeTranslation(tx, ty, tz);
geometry.applyMatrix4(m);
geometry.elementsNeedUpdate = true;
geometry.computeVertexNormals();
geometry.computeFaceNormals();
geometry.computeBoundingBox();
return geometry; //new BufferGeometry().fromGeometry(geometry);
}
/**
* Based on the DoorType the below method will change
* This can be replaced by the appropriate door model class
* This method will change with logic based on the door model type
*/
__createForDoorModel(frameWidth, openingDirection, materialId = 1) {
let gap = 0.25; //0.002;
let sf = this.__frameSize;
let wf = frameWidth - (sf * 2) - (gap * 2);
let hf = (this.__frameHeight / 2) - (gap * 2);
let deep = (this.__frameThickness * 0.50) - (gap * 3);
let side = 0,
minx = 0,
maxx = 0;
// # Open to right or left
if (openingDirection === DOOR_OPEN_DIRECTIONS.RIGHT) {
side = 1;
minx = wf * -1;
maxx = 0.0;
} else {
side = -1;
minx = 0.0;
maxx = wf;
}
let miny = 0.0; //# locked
let maxy = deep;
let minz = -hf;
let maxz = hf - sf; // - gap;
let faceids = [4, 5, 1, 0, 5, 6, 2, 1, 6, 7, 3, 2, 7, 4, 0, 3, 0, 1, 2, 3, 7, 6, 5, 4];
// # Vertex
let myvertex = [new Vector3(minx, miny, minz), new Vector3(minx, maxy, minz), new Vector3(maxx, maxy, minz), new Vector3(maxx, miny, minz), new Vector3(minx, miny, maxz), new Vector3(minx, maxy, maxz), new Vector3(maxx, maxy, maxz), new Vector3(maxx, miny, maxz)];
// # Faces
let myfaces = this.__convertFrom4ToFace3(faceids, materialId);
// let myfaces = [new Face3(4, 5, 1, 0), new Face3(5, 6, 2, 1), new Face3(6, 7, 3, 2), new Face3(7, 4, 0, 3), new Face3(0, 1, 2, 3), new Face3(7, 6, 5, 4)];
return { vertices: myvertex, faces: myfaces, widthFactor: wf, depth: deep, side: side };
}
get frameWidth() {
return this.__frameWidth;
}
set frameWidth(value) {
this.__frameWidth = (value) ? value : 100;
this.__updateGeometry();
}
get frameHeight() {
return this.__frameHeight;
}
set frameHeight(value) {
this.__frameHeight = (value) ? value : 200;
this.__updateGeometry();
}
get frameThickness() {
return this.__frameThickness;
}
set frameThickness(value) {
this.__frameThickness = (value) ? value : 20;
this.__updateGeometry();
}
get frameSize() {
return this.__frameSize;
}
set frameSize(value) {
this.__frameSize = Math.max(5, Math.min(25, value)); //Expressed in centimeters
this.__updateGeometry();
}
get doorRatio() {
return this.__doorRatio;
}
set doorRatio(value) {
this.__doorRatio = Math.max(0.0, Math.min(1.0, value)); //Expressed as a ratio between 0 -> 1
this.__updateGeometry();
}
get doorHandleColor() {
return `#${this.__doorHandleMaterial.color.getHexString()}`;
}
set doorHandleColor(color) {
this.__doorHandleMaterial.color = new Color(color);
this.__doorHandleMaterial.needsUpdate = true;
this.__material.needsUpdate = true;
}
get doorGlassColor() {
return `#${this.__glassMaterial.color.getHexString()}`;
}
set doorGlassColor(color) {
this.__glassMaterial.color = new Color(color);
this.__glassMaterial.needsUpdate = true;
this.__material.needsUpdate = true;
}
get doorColor() {
return `#${this.__doorMaterial.color.getHexString()}`;
}
set doorColor(color) {
this.__doorMaterial.color = new Color(color);
this.__doorMaterial.needsUpdate = true;
this.__material.needsUpdate = true;
}
get frameColor() {
return `#${this.__frameMaterial.color.getHexString()}`;
}
set frameColor(color) {
this.__frameMaterial.color = new Color(color);
this.__frameMaterial.needsUpdate = true;
this.__material.needsUpdate = true;
}
get openDirection() {
return this.__openDirection.description;
}
set openDirection(direction) {
switch (direction) {
case DOOR_OPEN_DIRECTIONS.RIGHT.description:
this.__openDirection = DOOR_OPEN_DIRECTIONS.RIGHT; //This value will be set in validatePArameters
break;
case DOOR_OPEN_DIRECTIONS.LEFT.description:
this.__openDirection = DOOR_OPEN_DIRECTIONS.LEFT; //This value will be set in validatePArameters
break;
case DOOR_OPEN_DIRECTIONS.BOTH_SIDES.description:
this.__openDirection = DOOR_OPEN_DIRECTIONS.BOTH_SIDES; //This value will be set in validatePArameters
break;
case DOOR_OPEN_DIRECTIONS.NO_DOORS.description:
this.__openDirection = DOOR_OPEN_DIRECTIONS.NO_DOORS; //This value will be set in validatePArameters
break;
}
this.__updateGeometry();
}
get handleType() {
return this.__handleType.description;
}
set handleType(type) {
switch (type) {
case DOOR_HANDLE_TYPES.None.description:
this.__handleType = DOOR_HANDLE_TYPES.None; //This value will be set in validatePArameters
break;
case DOOR_HANDLE_TYPES.HANDLE_01.description:
this.__handleType = DOOR_HANDLE_TYPES.HANDLE_01; //This value will be set in validatePArameters
break;
case DOOR_HANDLE_TYPES.HANDLE_02.description:
this.__handleType = DOOR_HANDLE_TYPES.HANDLE_02; //This value will be set in validatePArameters
break;
case DOOR_HANDLE_TYPES.HANDLE_03.description:
this.__handleType = DOOR_HANDLE_TYPES.HANDLE_03; //This value will be set in validatePArameters
break;
case DOOR_HANDLE_TYPES.HANDLE_04.description:
this.__handleType = DOOR_HANDLE_TYPES.HANDLE_04; //This value will be set in validatePArameters
break;
}
this.__updateGeometry();
}
get doorType() {
return this.__doorType;
}
get geometry() {
return this.__geometry;
}
get material() {
return this.__material;
}
get metadata() {
return {
type: this.__doorType,
frameColor: this.__frameMaterial.color,
doorColor: this.__doorMaterial.color,
doorHandleColor: this.__doorHandleMaterial.color,
glassColor: this.__glassMaterial.color,
frameWidth: this.frameWidth,
frameHeight: this.frameHeight,
frameSize: this.frameSize,
frameThickness: this.frameThickness,
doorRatio: this.doorRatio,
openDirection: this.__openDirection.description,
handleType: this.__handleType.description
};
}
get parameters() {
return {
frameColor: { type: 'color' },
doorColor: { type: 'color' },
doorHandleColor: { type: 'color' },
doorGlassColor: { type: 'color' },
frameWidth: { type: 'number' },
frameHeight: { type: 'number' },
frameSize: { type: 'range', min: 5, max: 25, step: 0.1 },
frameThickness: { type: 'number' },
doorRatio: { type: 'range', min: 0.2, max: 0.8, step: 0.001 },
openDirection: {
type: 'choice',
value: [
DOOR_OPEN_DIRECTIONS.RIGHT.description,
DOOR_OPEN_DIRECTIONS.LEFT.description,
DOOR_OPEN_DIRECTIONS.BOTH_SIDES.description,
DOOR_OPEN_DIRECTIONS.NO_DOORS.description
]
},
handleType: {
type: 'choice',
value: [
DOOR_HANDLE_TYPES.None.description,
DOOR_HANDLE_TYPES.HANDLE_01.description,
DOOR_HANDLE_TYPES.HANDLE_02.description,
DOOR_HANDLE_TYPES.HANDLE_03.description,
DOOR_HANDLE_TYPES.HANDLE_04.description
]
}
};
}
get name() {
return this.__name;
}
set name(value) {
this.__name = value;
}
}

147
src/blueprint/scripts/parametrics/doors/ParametricDoorType2.js

@ -0,0 +1,147 @@
import { ParametricBaseDoor, DOOR_OPEN_DIRECTIONS } from "./ParametricBaseDoor";
import { Vector3, Face3 } from "three";
export class ParametricDoorType2 extends ParametricBaseDoor {
constructor(parameters) {
super(parameters);
this.__doorType = 2;
}
/**
* Based on the DoorType the below method will change
* This can be replaced by the appropriate door model class
* This method will change with logic based on the door model type
*/
__createForDoorModel(frameWidth, openingDirection) {
let gap = 0.25; //0.002;
let sf = this.__frameSize;
let wf = frameWidth - (sf * 2) - (gap * 2);
let hf = (this.__frameHeight / 2) - (gap * 2);
let deep = (this.__frameThickness * 0.5);
let side = 0,
minx = 0,
maxx = 0;
// # Open to right or left
if (openingDirection === DOOR_OPEN_DIRECTIONS.RIGHT) {
side = 1;
minx = wf * -1;
maxx = 0.0;
} else {
side = -1;
minx = 0.0;
maxx = wf;
}
let miny = 0.0; //# locked
let maxy = deep;
let minz = -hf;
let maxz = hf - sf - gap;
let myvertex = [new Vector3(minx, (-1.57160684466362e-08 * 100), minz + (2.384185791015625e-06 * 100)),
new Vector3(maxx, (-1.5599653124809265e-08 * 100), minz),
new Vector3(minx, (-1.5599653124809265e-08 * 100), maxz),
new Vector3(minx, (-1.5599653124809265e-08 * 100), maxz - (0.12999999523162842 * 100)),
new Vector3(minx, (-1.57160684466362e-08 * 100), minz + (0.2500007152557373 * 100)),
new Vector3(maxx, (-1.5599653124809265e-08 * 100), minz + (0.25000011920928955 * 100)),
new Vector3(maxx, (-1.5599653124809265e-08 * 100), maxz),
new Vector3(maxx, (-1.5599653124809265e-08 * 100), maxz - (0.12999999523162842 * 100)),
new Vector3(maxx - (0.11609852313995361 * 100), (-1.5599653124809265e-08 * 100), maxz),
new Vector3(maxx - (0.12357193231582642 * 100), (-1.5599653124809265e-08 * 100), minz),
new Vector3(maxx - (0.11658430099487305 * 100), (-1.5599653124809265e-08 * 100), maxz - (0.12999999523162842 * 100)),
new Vector3(maxx - (0.12263774871826172 * 100), (-1.5599653124809265e-08 * 100), minz + (0.25000011920928955 * 100)),
new Vector3(minx, (-1.57160684466362e-08 * 100), minz + (0.8700000941753387 * 100)),
new Vector3(maxx, (-1.5599653124809265e-08 * 100), minz + (0.8700000941753387 * 100)),
new Vector3(maxx - (0.12076938152313232 * 100), (-1.5599653124809265e-08 * 100), minz + (0.7500001192092896 * 100)),
new Vector3(minx + (0.11735659837722778 * 100), (-1.57160684466362e-08 * 100), minz + (0.25000011920928955 * 100)),
new Vector3(minx + (0.12341010570526123 * 100), (-1.5599653124809265e-08 * 100), maxz - (0.12999999523162842 * 100)),
new Vector3(minx + (0.11642247438430786 * 100), (-1.57160684466362e-08 * 100), minz),
new Vector3(minx + (0.11967337131500244 * 100), (-1.57160684466362e-08 * 100), minz + (0.8700000941753387 * 100)),
new Vector3(minx, (-1.57160684466362e-08 * 100), minz + (0.7500001192092896 * 100)),
new Vector3(maxx - (0.12032097578048706 * 100), (-1.5599653124809265e-08 * 100), minz + (0.8700000941753387 * 100)),
new Vector3(minx + (0.12389582395553589 * 100), (-1.5599653124809265e-08 * 100), maxz),
new Vector3(maxx, (-1.5599653124809265e-08 * 100), minz + (0.7500001192092896 * 100)),
new Vector3(minx + (0.11922496557235718 * 100), (-1.57160684466362e-08 * 100), minz + (0.7500001192092896 * 100)),
new Vector3(minx + (0.11922496557235718 * 100), (-0.010000014677643776 * 100), minz + (0.7500001192092896 * 100)),
new Vector3(minx + (0.12341010570526123 * 100), (-0.010000014677643776 * 100), maxz - (0.12999999523162842 * 100)),
new Vector3(maxx - (0.12032097578048706 * 100), (-0.010000014677643776 * 100), minz + (0.8700000941753387 * 100)),
new Vector3(minx + (0.11735659837722778 * 100), (-0.010000014677643776 * 100), minz + (0.25000011920928955 * 100)),
new Vector3(maxx - (0.11658430099487305 * 100), (-0.010000014677643776 * 100), maxz - (0.12999999523162842 * 100)),
new Vector3(maxx - (0.12263774871826172 * 100), (-0.010000014677643776 * 100), minz + (0.25000011920928955 * 100)),
new Vector3(minx + (0.11967337131500244 * 100), (-0.010000014677643776 * 100), minz + (0.8700000941753387 * 100)),
new Vector3(maxx - (0.12076938152313232 * 100), (-0.010000014677643776 * 100), minz + (0.7500001192092896 * 100)),
new Vector3(minx + (0.13388586044311523 * 100), (-0.010000014677643776 * 100), minz + (0.7375001013278961 * 100)),
new Vector3(minx + (0.1321108341217041 * 100), (-0.010000014677643776 * 100), minz + (0.2625001072883606 * 100)),
new Vector3(maxx - (0.1372986137866974 * 100), (-0.010000014677643776 * 100), minz + (0.2625001072883606 * 100)),
new Vector3(maxx - (0.13552364706993103 * 100), (-0.010000014677643776 * 100), minz + (0.7375001013278961 * 100)),
new Vector3(minx + (0.13802427053451538 * 100), (-0.010000014677643776 * 100), maxz - (0.14747536182403564 * 100)),
new Vector3(maxx - (0.13493508100509644 * 100), (-0.010000014677643776 * 100), minz + (0.8866067305207253 * 100)),
new Vector3(maxx - (0.13138526678085327 * 100), (-0.010000014677643776 * 100), maxz - (0.14747536182403564 * 100)),
new Vector3(minx + (0.13447439670562744 * 100), (-0.010000014677643776 * 100), minz + (0.8866067305207253 * 100)),
new Vector3(minx + (0.13388586044311523 * 100), (-0.008776669390499592 * 100), minz + (0.7375001013278961 * 100)),
new Vector3(minx + (0.1321108341217041 * 100), (-0.008776669390499592 * 100), minz + (0.2625001072883606 * 100)),
new Vector3(maxx - (0.1372986137866974 * 100), (-0.008776669390499592 * 100), minz + (0.2625001072883606 * 100)),
new Vector3(maxx - (0.13552364706993103 * 100), (-0.008776669390499592 * 100), minz + (0.7375001013278961 * 100)),
new Vector3(minx + (0.13802427053451538 * 100), (-0.008776669390499592 * 100), maxz - (0.14747536182403564 * 100)),
new Vector3(maxx - (0.13493508100509644 * 100), (-0.008776669390499592 * 100), minz + (0.8866067305207253 * 100)),
new Vector3(maxx - (0.13138526678085327 * 100), (-0.008776669390499592 * 100), maxz - (0.14747536182403564 * 100)),
new Vector3(minx + (0.13447439670562744 * 100), (-0.008776669390499592 * 100), minz + (0.8866067305207253 * 100)),
new Vector3(minx, maxy - (0.009999999776482582 * 100), minz + (2.384185791015625e-06 * 100)),
new Vector3(maxx, maxy - (0.009999999776482582 * 100), minz),
new Vector3(minx, maxy - (0.009999999776482582 * 100), maxz),
new Vector3(minx, maxy - (0.009999999776482582 * 100), maxz - (0.12999999523162842 * 100)),
new Vector3(minx, maxy - (0.009999999776482582 * 100), minz + (0.2500007152557373 * 100)),
new Vector3(maxx, maxy - (0.009999999776482582 * 100), minz + (0.25000011920928955 * 100)),
new Vector3(maxx, maxy - (0.009999999776482582 * 100), maxz),
new Vector3(maxx, maxy - (0.009999999776482582 * 100), maxz - (0.12999999523162842 * 100)),
new Vector3(maxx - (0.11609852313995361 * 100), maxy - (0.009999999776482582 * 100), maxz),
new Vector3(maxx - (0.12357193231582642 * 100), maxy - (0.009999999776482582 * 100), minz),
new Vector3(maxx - (0.11658430099487305 * 100), maxy - (0.009999999776482582 * 100), maxz - (0.12999999523162842 * 100)),
new Vector3(maxx - (0.12263774871826172 * 100), maxy - (0.009999999776482582 * 100), minz + (0.25000011920928955 * 100)),
new Vector3(minx, maxy - (0.009999999776482582 * 100), minz + (0.8700000941753387 * 100)),
new Vector3(maxx, maxy - (0.009999999776482582 * 100), minz + (0.8700000941753387 * 100)),
new Vector3(maxx - (0.12076938152313232 * 100), maxy - (0.009999999776482582 * 100), minz + (0.7500001192092896 * 100)),
new Vector3(minx + (0.11735659837722778 * 100), maxy - (0.009999999776482582 * 100), minz + (0.25000011920928955 * 100)),
new Vector3(minx + (0.12341010570526123 * 100), maxy - (0.009999999776482582 * 100), maxz - (0.12999999523162842 * 100)),
new Vector3(minx + (0.11642247438430786 * 100), maxy - (0.009999999776482582 * 100), minz),
new Vector3(minx + (0.11967337131500244 * 100), maxy - (0.009999999776482582 * 100), minz + (0.8700000941753387 * 100)),
new Vector3(minx, maxy - (0.009999999776482582 * 100), minz + (0.7500001192092896 * 100)),
new Vector3(maxx - (0.12032097578048706 * 100), maxy - (0.009999999776482582 * 100), minz + (0.8700000941753387 * 100)),
new Vector3(minx + (0.12389582395553589 * 100), maxy - (0.009999999776482582 * 100), maxz),
new Vector3(maxx, maxy - (0.009999999776482582 * 100), minz + (0.7500001192092896 * 100)),
new Vector3(minx + (0.11922496557235718 * 100), maxy - (0.009999999776482582 * 100), minz + (0.7500001192092896 * 100)),
new Vector3(minx + (0.11922496557235718 * 100), maxy, minz + (0.7500001192092896 * 100)),
new Vector3(minx + (0.12341010570526123 * 100), maxy, maxz - (0.12999999523162842 * 100)),
new Vector3(maxx - (0.12032097578048706 * 100), maxy, minz + (0.8700000941753387 * 100)),
new Vector3(minx + (0.11735659837722778 * 100), maxy, minz + (0.25000011920928955 * 100)),
new Vector3(maxx - (0.11658430099487305 * 100), maxy, maxz - (0.12999999523162842 * 100)),
new Vector3(maxx - (0.12263774871826172 * 100), maxy, minz + (0.25000011920928955 * 100)),
new Vector3(minx + (0.11967337131500244 * 100), maxy, minz + (0.8700000941753387 * 100)),
new Vector3(maxx - (0.12076938152313232 * 100), maxy, minz + (0.7500001192092896 * 100)),
new Vector3(minx + (0.13388586044311523 * 100), maxy, minz + (0.7375001013278961 * 100)),
new Vector3(minx + (0.1321108341217041 * 100), maxy, minz + (0.2625001072883606 * 100)),
new Vector3(maxx - (0.1372986137866974 * 100), maxy, minz + (0.2625001072883606 * 100)),
new Vector3(maxx - (0.13552364706993103 * 100), maxy, minz + (0.7375001013278961 * 100)),
new Vector3(minx + (0.13802427053451538 * 100), maxy, maxz - (0.14747536182403564 * 100)),
new Vector3(maxx - (0.13493508100509644 * 100), maxy, minz + (0.8866067305207253 * 100)),
new Vector3(maxx - (0.13138526678085327 * 100), maxy, maxz - (0.14747536182403564 * 100)),
new Vector3(minx + (0.13447439670562744 * 100), maxy, minz + (0.8866067305207253 * 100)),
new Vector3(minx + (0.13388586044311523 * 100), maxy - (0.0012233443558216095 * 100), minz + (0.7375001013278961 * 100)),
new Vector3(minx + (0.1321108341217041 * 100), maxy - (0.0012233443558216095 * 100), minz + (0.2625001072883606 * 100)),
new Vector3(maxx - (0.1372986137866974 * 100), maxy - (0.0012233443558216095 * 100), minz + (0.2625001072883606 * 100)),
new Vector3(maxx - (0.13552364706993103 * 100), maxy - (0.0012233443558216095 * 100), minz + (0.7375001013278961 * 100)),
new Vector3(minx + (0.13802427053451538 * 100), maxy - (0.0012233443558216095 * 100), maxz - (0.14747536182403564 * 100)),
new Vector3(maxx - (0.13493508100509644 * 100), maxy - (0.0012233443558216095 * 100), minz + (0.8866067305207253 * 100)),
new Vector3(maxx - (0.13138526678085327 * 100), maxy - (0.0012233443558216095 * 100), maxz - (0.14747536182403564 * 100)),
new Vector3(minx + (0.13447439670562744 * 100), maxy - (0.0012233443558216095 * 100), minz + (0.8866067305207253 * 100))
];
let myfaces = [new Face3(0, 4, 15), new Face3(17, 0, 15), new Face3(3, 2, 21), new Face3(16, 3, 21), new Face3(4, 19, 23), new Face3(15, 4, 23), new Face3(10, 8, 6), new Face3(7, 10, 6), new Face3(16, 21, 8), new Face3(10, 16, 8), new Face3(12, 3, 16), new Face3(18, 12, 16), new Face3(17, 15, 11), new Face3(9, 17, 11), new Face3(23, 18, 20), new Face3(14, 23, 20), new Face3(19, 12, 18), new Face3(23, 19, 18), new Face3(9, 11, 5), new Face3(1, 9, 5), new Face3(11, 14, 22), new Face3(5, 11, 22), new Face3(20, 10, 7), new Face3(13, 20, 7), new Face3(14, 20, 13), new Face3(22, 14, 13), new Face3(28, 10, 20), new Face3(26, 28, 20), new Face3(25, 16, 10), new Face3(28, 25, 10), new Face3(30, 18, 16), new Face3(25, 30, 16), new Face3(26, 20, 18), new Face3(30, 26, 18), new Face3(29, 11, 15), new Face3(27, 29, 15), new Face3(24, 23, 14), new Face3(31, 24, 14), new Face3(27, 15, 23), new Face3(24, 27, 23), new Face3(31, 14, 11), new Face3(29, 31, 11), new Face3(32, 24, 31), new Face3(35, 32, 31), new Face3(33, 27, 24), new Face3(32, 33, 24), new Face3(34, 29, 27), new Face3(33, 34, 27), new Face3(35, 31, 29), new Face3(34, 35, 29), new Face3(38, 28, 26), new Face3(37, 38, 26), new Face3(37, 26, 30), new Face3(39, 37, 30), new Face3(36, 25, 28), new Face3(38, 36, 28), new Face3(39, 30, 25), new Face3(36, 39, 25), new Face3(42, 34, 33), new Face3(41, 42, 33), new Face3(47, 39, 36), new Face3(44, 47, 36), new Face3(43, 35, 34), new Face3(42, 43, 34), new Face3(46, 38, 37), new Face3(45, 46, 37), new Face3(41, 33, 32), new Face3(40, 41, 32), new Face3(44, 36, 38), new Face3(46, 44, 38), new Face3(40, 32, 35), new Face3(43, 40, 35), new Face3(45, 37, 39), new Face3(47, 45, 39), new Face3(10, 20, 18), new Face3(16, 10, 18), new Face3(15, 23, 14), new Face3(11, 15, 14), new Face3(48, 52, 63), new Face3(65, 48, 63), new Face3(51, 50, 69), new Face3(64, 51, 69), new Face3(52, 67, 71), new Face3(63, 52, 71), new Face3(58, 56, 54), new Face3(55, 58, 54), new Face3(64, 69, 56), new Face3(58, 64, 56), new Face3(60, 51, 64), new Face3(66, 60, 64), new Face3(65, 63, 59), new Face3(57, 65, 59), new Face3(71, 66, 68), new Face3(62, 71, 68), new Face3(67, 60, 66), new Face3(71, 67, 66), new Face3(57, 59, 53), new Face3(49, 57, 53), new Face3(59, 62, 70), new Face3(53, 59, 70), new Face3(68, 58, 55), new Face3(61, 68, 55), new Face3(62, 68, 61), new Face3(70, 62, 61), new Face3(76, 58, 68), new Face3(74, 76, 68), new Face3(73, 64, 58), new Face3(76, 73, 58), new Face3(78, 66, 64), new Face3(73, 78, 64), new Face3(74, 68, 66), new Face3(78, 74, 66), new Face3(77, 59, 63), new Face3(75, 77, 63), new Face3(72, 71, 62), new Face3(79, 72, 62), new Face3(75, 63, 71), new Face3(72, 75, 71), new Face3(79, 62, 59), new Face3(77, 79, 59), new Face3(80, 72, 79), new Face3(83, 80, 79), new Face3(81, 75, 72), new Face3(80, 81, 72), new Face3(82, 77, 75), new Face3(81, 82, 75), new Face3(83, 79, 77), new Face3(82, 83, 77), new Face3(86, 76, 74), new Face3(85, 86, 74), new Face3(85, 74, 78), new Face3(87, 85, 78), new Face3(84, 73, 76), new Face3(86, 84, 76), new Face3(87, 78, 73), new Face3(84, 87, 73), new Face3(90, 82, 81), new Face3(89, 90, 81), new Face3(95, 87, 84), new Face3(92, 95, 84), new Face3(91, 83, 82), new Face3(90, 91, 82), new Face3(94, 86, 85), new Face3(93, 94, 85), new Face3(89, 81, 80), new Face3(88, 89, 80), new Face3(92, 84, 86), new Face3(94, 92, 86), new Face3(88, 80, 83), new Face3(91, 88, 83), new Face3(93, 85, 87), new Face3(95, 93, 87), new Face3(58, 68, 66), new Face3(64, 58, 66), new Face3(63, 71, 62), new Face3(59, 63, 62), new Face3(21, 2, 50), new Face3(69, 21, 50), new Face3(69, 56, 8), new Face3(21, 69, 8), new Face3(56, 54, 6), new Face3(8, 56, 6), new Face3(7, 6, 54), new Face3(55, 7, 54), new Face3(13, 7, 55), new Face3(61, 13, 55), new Face3(22, 13, 61), new Face3(70, 22, 61), new Face3(70, 53, 5), new Face3(22, 70, 5), new Face3(53, 49, 1), new Face3(5, 53, 1), new Face3(9, 1, 49), new Face3(57, 9, 49), new Face3(17, 9, 57), new Face3(65, 17, 57), new Face3(65, 48, 0), new Face3(17, 65, 0), new Face3(4, 0, 48), new Face3(52, 4, 48), new Face3(19, 4, 52), new Face3(67, 19, 52), new Face3(67, 60, 12), new Face3(19, 67, 12), new Face3(60, 51, 3), new Face3(12, 60, 3), new Face3(51, 50, 2), new Face3(3, 51, 2)];
let normal_ids = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187];
let glass_ids = [];
let i = 0;
for (i = 0; i < normal_ids.length; i++) { myfaces[normal_ids[i]].materialIndex = this.__doorMaterialId; }
for (i = 0; i < glass_ids.length; i++) { myfaces[glass_ids[i]].materialIndex = this.__glassMaterialId; }
return { vertices: myvertex, faces: myfaces, widthFactor: wf, depth: deep, side: side };
}
}

54
src/blueprint/scripts/parametrics/doors/ParametricDoorType3.js

File diff suppressed because one or more lines are too long

55
src/blueprint/scripts/parametrics/doors/ParametricDoorType4.js

File diff suppressed because one or more lines are too long

53
src/blueprint/scripts/parametrics/doors/ParametricDoorType5.js

File diff suppressed because one or more lines are too long

52
src/blueprint/scripts/parametrics/doors/ParametricDoorType6.js

File diff suppressed because one or more lines are too long

149
src/blueprint/scripts/parametrics/doors/doorhandles/DoorHandleGenerator.js

@ -0,0 +1,149 @@
import { Handle_01_vertices, Handle_01_faces } from './Handle_01';
import { Handle_02_vertices, Handle_02_faces } from './Handle_02';
import { Handle_03_vertices, Handle_03_faces } from './Handle_03';
import { Handle_04_vertices, Handle_04_faces } from './Handle_04';
import { Geometry, Matrix4, Vector3 } from 'three/build/three.module';
export class DoorHandleGenerator {
static generate_handle(handleType, frontOrBack, doorSide, doorRatio, frame_width, frame_size, frame_thickness, doorOpenDirection, materialId) {
let handle = null;
switch (handleType) {
case 'HANDLE_01':
handle = DoorHandleGenerator.handle_model_01(materialId);
break;
case 'HANDLE_02':
handle = DoorHandleGenerator.handle_model_02(materialId);
break;
case 'HANDLE_03':
handle = DoorHandleGenerator.handle_model_03(materialId);
break;
case 'HANDLE_04':
handle = DoorHandleGenerator.handle_model_04(materialId);
break;
}
if (handle) {
let side = 1;
let sf = frame_size;
let gap = 0.25; //0.002
let wf = frame_width - (sf * 2) - (gap * 2);
let deep = (frame_thickness * 0.5) - (gap * 3);
let offset = 10;
if (frontOrBack === 'Front') {
handle.applyMatrix4(new Matrix4().makeRotationAxis(new Vector3(1, 0, 0), -Math.PI * 0.5));
handle.applyMatrix4(new Matrix4().makeTranslation(0, 0, deep));
} else {
handle.applyMatrix4(new Matrix4().makeRotationAxis(new Vector3(1, 0, 0), Math.PI * 0.5));
handle.applyMatrix4(new Matrix4().makeTranslation(0, 0, -deep));
}
if (doorSide === 'Right' && doorOpenDirection !== 'BOTH_SIDES') {
handle.applyMatrix4(new Matrix4().makeRotationAxis(new Vector3(0, 0, 1), Math.PI));
handle.applyMatrix4(new Matrix4().makeTranslation(-offset, 0, 0));
} else if (doorSide === 'Left' && doorOpenDirection !== 'BOTH_SIDES') {
handle.applyMatrix4(new Matrix4().makeTranslation(offset, 0, 0));
} else if (doorSide !== 'Right' && doorOpenDirection === 'BOTH_SIDES') {
handle.applyMatrix4(new Matrix4().makeRotationAxis(new Vector3(0, 0, 1), -Math.PI));
}
if (doorOpenDirection === 'BOTH_SIDES' && doorSide === 'Left') {
handle.applyMatrix4(new Matrix4().makeTranslation((wf * doorRatio) - offset, 0, 0));
}
if (doorOpenDirection === 'BOTH_SIDES' && doorSide === 'Right') {
handle.applyMatrix4(new Matrix4().makeTranslation((-wf * doorRatio) + offset, 0, 0));
}
}
return handle;
}
// ----------------------------------------------
// Handle model 01
// ----------------------------------------------
static handle_model_01(materialId = 4) {
let geometry = new Geometry();
let vertices = [];
let faces = [];
Handle_01_vertices.forEach((vertex) => {
vertices.push(vertex.clone());
});
Handle_01_faces.forEach((face) => {
let face2 = face.clone();
face2.materialIndex = materialId;
faces.push(face2);
});
geometry.vertices = vertices;
geometry.faces = faces;
geometry.computeVertexNormals();
geometry.computeFaceNormals();
geometry.computeBoundingBox();
return geometry;
}
static handle_model_02(materialId = 4) {
let geometry = new Geometry();
let vertices = [];
let faces = [];
Handle_02_vertices.forEach((vertex) => {
vertices.push(vertex.clone());
});
Handle_02_faces.forEach((face) => {
let face2 = face.clone();
face2.materialIndex = materialId;
faces.push(face2);
});
geometry.vertices = vertices;
geometry.faces = faces;
geometry.elementsNeedUpdate = true;
geometry.computeVertexNormals();
geometry.computeFaceNormals();
geometry.computeBoundingBox();
return geometry;
}
static handle_model_03(materialId = 4) {
let geometry = new Geometry();
let vertices = [];
let faces = [];
Handle_03_vertices.forEach((vertex) => {
vertices.push(vertex.clone());
});
Handle_03_faces.forEach((face) => {
let face2 = face.clone();
face2.materialIndex = materialId;
faces.push(face2);
});
geometry.vertices = vertices;
geometry.faces = faces;
geometry.computeVertexNormals();
geometry.computeFaceNormals();
geometry.computeBoundingBox();
return geometry;
}
static handle_model_04(materialId = 4) {
let geometry = new Geometry();
let vertices = [];
let faces = [];
Handle_04_vertices.forEach((vertex) => {
vertices.push(vertex.clone());
});
Handle_04_faces.forEach((face) => {
let face2 = face.clone();
face2.materialIndex = materialId;
faces.push(face2);
});
geometry.vertices = vertices;
geometry.faces = faces;
geometry.computeVertexNormals();
geometry.computeFaceNormals();
geometry.computeBoundingBox();
return geometry;
}
}

5
src/blueprint/scripts/parametrics/doors/doorhandles/Handle_01.js

File diff suppressed because one or more lines are too long

5
src/blueprint/scripts/parametrics/doors/doorhandles/Handle_02.js

File diff suppressed because one or more lines are too long

5
src/blueprint/scripts/parametrics/doors/doorhandles/Handle_03.js

File diff suppressed because one or more lines are too long

5
src/blueprint/scripts/parametrics/doors/doorhandles/Handle_04.js

File diff suppressed because one or more lines are too long

290
src/blueprint/scripts/tempSrc/LShape.json

@ -0,0 +1,290 @@
{
"floorplan": {
"version": "2.0.1a",
"corners": {
"4ae6fabe-5cdc-ec3a-c858-f4537b0bd0b1": {
"x": 0,
"y": -5,
"elevation": 2.5
},
"a103d9da-46bd-88c7-3710-e0323ac74352": {
"x": 10,
"y": -5,
"elevation": 2.5
},
"718bc5a1-ef34-deaf-3e91-b7289a043090": {
"x": 10,
"y": 5,
"elevation": 2.5
},
"732d5821-5f91-217d-79aa-e8d11c51e97f": {
"x": 5,
"y": 5,
"elevation": 2.5
},
"47ad5165-6d74-ff0c-32c9-3f2660a988b5": {
"x": 5,
"y": 0,
"elevation": 2.5
},
"331a6234-c305-ab4c-2d4a-4aa69be00cab": {
"x": 0,
"y": 0,
"elevation": 2.5
}
},
"walls": [
{
"corner1": "4ae6fabe-5cdc-ec3a-c858-f4537b0bd0b1",
"corner2": "a103d9da-46bd-88c7-3710-e0323ac74352",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png",
"emissive": "#000000",
"reflective": 0.5,
"shininess": 0.5
},
"backTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png",
"emissive": "#000000",
"reflective": 0.5,
"shininess": 0.5
},
"wallType": "STRAIGHT",
"a": {
"x": -146.44660940672622,
"y": -146.44660940672628
},
"b": {
"x": 146.44660940672628,
"y": -146.44660940672622
},
"thickness": 0.2
},
{
"corner1": "a103d9da-46bd-88c7-3710-e0323ac74352",
"corner2": "718bc5a1-ef34-deaf-3e91-b7289a043090",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png",
"emissive": "#000000",
"reflective": 0.5,
"shininess": 0.5
},
"backTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png",
"emissive": "#000000",
"reflective": 0.5,
"shininess": 0.5
},
"wallType": "STRAIGHT",
"a": {
"x": 146.44660940672628,
"y": -146.44660940672622
},
"b": {
"x": 146.44660940672622,
"y": 146.44660940672628
},
"thickness": 0.2
},
{
"corner1": "718bc5a1-ef34-deaf-3e91-b7289a043090",
"corner2": "732d5821-5f91-217d-79aa-e8d11c51e97f",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png",
"emissive": "#000000",
"reflective": 0.5,
"shininess": 0.5
},
"backTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png",
"emissive": "#000000",
"reflective": 0.5,
"shininess": 0.5
},
"wallType": "STRAIGHT",
"a": {
"x": 323.2233047033631,
"y": 323.22330470336317
},
"b": {
"x": 176.77669529663686,
"y": 323.2233047033631
},
"thickness": 0.2
},
{
"corner1": "732d5821-5f91-217d-79aa-e8d11c51e97f",
"corner2": "47ad5165-6d74-ff0c-32c9-3f2660a988b5",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png",
"emissive": "#000000",
"reflective": 0.5,
"shininess": 0.5
},
"backTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png",
"emissive": "#000000",
"reflective": 0.5,
"shininess": 0.5
},
"wallType": "STRAIGHT",
"a": {
"x": 176.77669529663686,
"y": 323.2233047033631
},
"b": {
"x": 176.7766952966369,
"y": 176.77669529663686
},
"thickness": 0.2
},
{
"corner1": "47ad5165-6d74-ff0c-32c9-3f2660a988b5",
"corner2": "331a6234-c305-ab4c-2d4a-4aa69be00cab",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png",
"emissive": "#000000",
"reflective": 0.5,
"shininess": 0.5
},
"backTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png",
"emissive": "#000000",
"reflective": 0.5,
"shininess": 0.5
},
"wallType": "STRAIGHT",
"a": {
"x": -176.7766952966369,
"y": -176.77669529663686
},
"b": {
"x": -323.22330470336317,
"y": -176.7766952966369
},
"thickness": 0.2
},
{
"corner1": "331a6234-c305-ab4c-2d4a-4aa69be00cab",
"corner2": "4ae6fabe-5cdc-ec3a-c858-f4537b0bd0b1",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png",
"emissive": "#000000",
"reflective": 0.5,
"shininess": 0.5
},
"backTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png",
"emissive": "#000000",
"reflective": 0.5,
"shininess": 0.5
},
"wallType": "STRAIGHT",
"a": {
"x": -323.22330470336317,
"y": -176.7766952966369
},
"b": {
"x": -323.2233047033631,
"y": -323.22330470336317
},
"thickness": 0.2
}
],
"rooms": {
"4ae6fabe-5cdc-ec3a-c858-f4537b0bd0b1,a103d9da-46bd-88c7-3710-e0323ac74352,718bc5a1-ef34-deaf-3e91-b7289a043090,732d5821-5f91-217d-79aa-e8d11c51e97f,47ad5165-6d74-ff0c-32c9-3f2660a988b5,331a6234-c305-ab4c-2d4a-4aa69be00cab": {
"name": "Corridor"
}
},
"wallTextures": [],
"floorTextures": {},
"newFloorTextures": {
"331a6234-c305-ab4c-2d4a-4aa69be00cab,47ad5165-6d74-ff0c-32c9-3f2660a988b5,4ae6fabe-5cdc-ec3a-c858-f4537b0bd0b1,718bc5a1-ef34-deaf-3e91-b7289a043090,732d5821-5f91-217d-79aa-e8d11c51e97f,a103d9da-46bd-88c7-3710-e0323ac74352": {
"color": "#FFFFFF",
"emissive": "#181818",
"repeat": 300,
"ambientmap": "textures/Floor/Marble_Tiles_001/Marble_Tiles_001_ambientOcclusion.jpg",
"colormap": "textures/Floor/Marble_Tiles_001/Marble_Tiles_001_basecolor.jpg",
"roughnessmap": "textures/Floor/Marble_Tiles_001/Marble_Tiles_001_roughness.jpg",
"normalmap": "textures/Floor/Marble_Tiles_001/Marble_Tiles_001_normal.jpg",
"reflective": 0.5,
"shininess": 0.5
}
},
"carbonSheet": {},
"units": "m"
},
"items": []
}

194
src/blueprint/scripts/tempSrc/designWithBoundary.json

@ -0,0 +1,194 @@
{
"floorplan": {
"version": "2.0.1a",
"boundary": {
"points": [
{"x":-20.0, "y": -20.0, "elevation": 5.0},
{"x":20.0, "y": -20.0, "elevation": 5.0},
{"x":20.0, "y": 20.0, "elevation": 5.0},
{"x":-20.0, "y": 20.0, "elevation": 5.0},
],
"style": {
"color": "#00FF00",
"type": "texture",
"colormap": "textures/Ground/GrassTextureDeviantArt.jpg",
"repeat": 3000
}
},
"corners": {
"71d4f128-ae80-3d58-9bd2-711c6ce6cdf2": {
"x": 0,
"y": 0,
"elevation": 2.5
},
"f90da5e3-9e0e-eba7-173d-eb0b071e838e": {
"x": 0,
"y": 5,
"elevation": 2.5
},
"da026c08-d76a-a944-8e7b-096b752da9ed": {
"x": 5,
"y": 5,
"elevation": 2.5
},
"4e3d65cb-54c0-0681-28bf-bddcc7bdb571": {
"x": 5,
"y": 0,
"elevation": 2.5
}
},
"walls": [{
"corner1": "71d4f128-ae80-3d58-9bd2-711c6ce6cdf2",
"corner2": "f90da5e3-9e0e-eba7-173d-eb0b071e838e",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png"
},
"backTexture": {
"repeat": 200,
"colormap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_basecolor.jpg",
"bumpmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_height.png",
"normalmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_normal.jpg",
"roughnessmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_roughness.jpg",
"ambientmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_ambientocclusion.jpg",
"color": "#FFFFFF"
},
"wallType": "STRAIGHT",
"a": {
"x": -176.77669529663686,
"y": 176.7766952966369
},
"b": {
"x": -176.7766952966369,
"y": 323.22330470336317
},
"thickness": 0.2
},
{
"corner1": "f90da5e3-9e0e-eba7-173d-eb0b071e838e",
"corner2": "da026c08-d76a-a944-8e7b-096b752da9ed",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png"
},
"backTexture": {
"repeat": 200,
"colormap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_basecolor.jpg",
"bumpmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_height.png",
"normalmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_normal.jpg",
"roughnessmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_roughness.jpg",
"ambientmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_ambientocclusion.jpg",
"color": "#FFFFFF"
},
"wallType": "STRAIGHT",
"a": {
"x": 176.7766952966369,
"y": 676.7766952966368
},
"b": {
"x": 323.22330470336317,
"y": 676.776695296637
},
"thickness": 0.2
},
{
"corner1": "da026c08-d76a-a944-8e7b-096b752da9ed",
"corner2": "4e3d65cb-54c0-0681-28bf-bddcc7bdb571",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png"
},
"backTexture": {
"repeat": 200,
"colormap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_basecolor.jpg",
"bumpmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_height.png",
"normalmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_normal.jpg",
"roughnessmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_roughness.jpg",
"ambientmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_ambientocclusion.jpg",
"color": "#FFFFFF"
},
"wallType": "STRAIGHT",
"a": {
"x": 676.7766952966368,
"y": 323.2233047033631
},
"b": {
"x": 676.776695296637,
"y": 176.77669529663686
},
"thickness": 0.2
},
{
"corner1": "4e3d65cb-54c0-0681-28bf-bddcc7bdb571",
"corner2": "71d4f128-ae80-3d58-9bd2-711c6ce6cdf2",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png"
},
"backTexture": {
"repeat": 200,
"colormap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_basecolor.jpg",
"bumpmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_height.png",
"normalmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_normal.jpg",
"roughnessmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_roughness.jpg",
"ambientmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_ambientocclusion.jpg",
"color": "#FFFFFF"
},
"wallType": "STRAIGHT",
"a": {
"x": 323.2233047033631,
"y": -176.77669529663686
},
"b": {
"x": 176.77669529663686,
"y": -176.7766952966369
},
"thickness": 0.2
}
],
"rooms": {
"71d4f128-ae80-3d58-9bd2-711c6ce6cdf2,4e3d65cb-54c0-0681-28bf-bddcc7bdb571,da026c08-d76a-a944-8e7b-096b752da9ed,f90da5e3-9e0e-eba7-173d-eb0b071e838e": {
"name": "A Room"
}
},
"wallTextures": [],
"floorTextures": {},
"newFloorTextures": {
"4e3d65cb-54c0-0681-28bf-bddcc7bdb571,71d4f128-ae80-3d58-9bd2-711c6ce6cdf2,da026c08-d76a-a944-8e7b-096b752da9ed,f90da5e3-9e0e-eba7-173d-eb0b071e838e": {
"repeat": 100,
"roughnessmap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_roughness.jpg",
"ambientmap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_ambientOcclusion.jpg",
"normalmap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_normal.jpg",
"colormap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_basecolor.jpg",
"color": "#FFFFFF",
"emissive": "#000000",
"reflective": 0.5,
"shininess": 0.5,
}
},
"carbonSheet": {},
"units": "m"
},
"items": [
]
}

404
src/blueprint/scripts/tempSrc/designWithoutBoundary.json

@ -0,0 +1,404 @@
{
"floorplan": {
"version": "2.0.1a",
"corners": {
"71d4f128-ae80-3d58-9bd2-711c6ce6cdf2": {
"x": 0,
"y": 0,
"elevation": 2.5
},
"f90da5e3-9e0e-eba7-173d-eb0b071e838e": {
"x": 0,
"y": 5,
"elevation": 2.5
},
"da026c08-d76a-a944-8e7b-096b752da9ed": {
"x": 5,
"y": 5,
"elevation": 2.5
},
"4e3d65cb-54c0-0681-28bf-bddcc7bdb571": {
"x": 5,
"y": 0,
"elevation": 2.5
}
},
"walls": [{
"corner1": "71d4f128-ae80-3d58-9bd2-711c6ce6cdf2",
"corner2": "f90da5e3-9e0e-eba7-173d-eb0b071e838e",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png"
},
"backTexture": {
"repeat": 200,
"colormap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_basecolor.jpg",
"bumpmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_height.png",
"normalmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_normal.jpg",
"roughnessmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_roughness.jpg",
"ambientmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_ambientocclusion.jpg",
"color": "#FFFFFF"
},
"wallType": "STRAIGHT",
"a": {
"x": -176.77669529663686,
"y": 176.7766952966369
},
"b": {
"x": -176.7766952966369,
"y": 323.22330470336317
},
"thickness": 0.2
},
{
"corner1": "f90da5e3-9e0e-eba7-173d-eb0b071e838e",
"corner2": "da026c08-d76a-a944-8e7b-096b752da9ed",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png"
},
"backTexture": {
"repeat": 200,
"colormap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_basecolor.jpg",
"bumpmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_height.png",
"normalmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_normal.jpg",
"roughnessmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_roughness.jpg",
"ambientmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_ambientocclusion.jpg",
"color": "#FFFFFF"
},
"wallType": "STRAIGHT",
"a": {
"x": 176.7766952966369,
"y": 676.7766952966368
},
"b": {
"x": 323.22330470336317,
"y": 676.776695296637
},
"thickness": 0.2
},
{
"corner1": "da026c08-d76a-a944-8e7b-096b752da9ed",
"corner2": "4e3d65cb-54c0-0681-28bf-bddcc7bdb571",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png"
},
"backTexture": {
"repeat": 200,
"colormap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_basecolor.jpg",
"bumpmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_height.png",
"normalmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_normal.jpg",
"roughnessmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_roughness.jpg",
"ambientmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_ambientocclusion.jpg",
"color": "#FFFFFF"
},
"wallType": "STRAIGHT",
"a": {
"x": 676.7766952966368,
"y": 323.2233047033631
},
"b": {
"x": 676.776695296637,
"y": 176.77669529663686
},
"thickness": 0.2
},
{
"corner1": "4e3d65cb-54c0-0681-28bf-bddcc7bdb571",
"corner2": "71d4f128-ae80-3d58-9bd2-711c6ce6cdf2",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png"
},
"backTexture": {
"repeat": 200,
"colormap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_basecolor.jpg",
"bumpmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_height.png",
"normalmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_normal.jpg",
"roughnessmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_roughness.jpg",
"ambientmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_ambientocclusion.jpg",
"color": "#FFFFFF"
},
"wallType": "STRAIGHT",
"a": {
"x": 323.2233047033631,
"y": -176.77669529663686
},
"b": {
"x": 176.77669529663686,
"y": -176.7766952966369
},
"thickness": 0.2
}
],
"rooms": {
"71d4f128-ae80-3d58-9bd2-711c6ce6cdf2,4e3d65cb-54c0-0681-28bf-bddcc7bdb571,da026c08-d76a-a944-8e7b-096b752da9ed,f90da5e3-9e0e-eba7-173d-eb0b071e838e": {
"name": "A Room"
}
},
"wallTextures": [],
"floorTextures": {},
"newFloorTextures": {
"4e3d65cb-54c0-0681-28bf-bddcc7bdb571,71d4f128-ae80-3d58-9bd2-711c6ce6cdf2,da026c08-d76a-a944-8e7b-096b752da9ed,f90da5e3-9e0e-eba7-173d-eb0b071e838e": {
"repeat": 100,
"roughnessmap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_roughness.jpg",
"ambientmap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_ambientOcclusion.jpg",
"normalmap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_normal.jpg",
"colormap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_basecolor.jpg",
"color": "#FFFFFF",
"emissive": "#000000",
"reflective": 0.5,
"shininess": 0.5,
}
},
"carbonSheet": {},
"units": "m"
},
"items": [{
"id": "7d0b3e90-c315-e7a5-a6d9-594757d5b7e4",
"itemName": "An Item",
"itemType": 3,
"position": [
10,
138.38790186348007,
185.34460161835352
],
"rotation": [
0,
1.5707963267948966,
0
],
"scale": [
1,
1,
1
],
"size": [
240,
100,
50
],
"fixed": true,
"resizable": true,
"modelURL": "models/HollowCube.glb",
"isParametric": false,
"wall": "71d4f128-ae80-3d58-9bd2-711c6ce6cdf2,f90da5e3-9e0e-eba7-173d-eb0b071e838e",
"wallSide": "back",
"wallSurfacePoint": [
10,
138.38790186348007,
185.34460161835352
]
},
{
"itemName": "Tennis Table",
"itemType": 1,
"position": [
280,
50,
350
],
"rotation": [
0,
0,
0
],
"scale": [
1,
1,
1
],
"size": [
281.598,
98.1,
172.4
],
"fixed": false,
"resizable": false,
"modelURL": "models/TableTennisTable.glb",
"isParametric": false
},
{
"itemName": "Andrea Wox Table",
"itemType": 1,
"position": [
280,
25,
130
],
"rotation": [
0,
0,
0
],
"scale": [
1,
1,
1
],
"size": [
161.0,
51.8,
161.0
],
"fixed": false,
"resizable": false,
"modelURL": "models/AndreaWox_Table_Resized.glb",
"isParametric": false
},
{
"itemName": "DoubleChairWithPillow",
"itemType": 9,
"position": [
99.27116005634912,
41.36685,
49.64319999999989
],
"rotation": [
0,
0,
0
],
"scale": [
1,
1,
1
],
"size": [
108.85,
72.7337,
69.2864
],
"fixed": false,
"resizable": false,
"modelURL": "models/DoubleChairWithPillow.glb",
"isParametric": false,
"wall": "4e3d65cb-54c0-0681-28bf-bddcc7bdb571,71d4f128-ae80-3d58-9bd2-711c6ce6cdf2",
"wallSide": "back",
"wallSurfacePoint": [
99.27116005634912,
70.88314014751387,
9.999999999999886
]
},
{
"itemName": "Parametric Door 01",
"isParametric": true,
"baseParametricType": "DOOR",
"subParametricData": {
"type": 6,
"frameColor": 15198183,
"doorColor": 15198183,
"doorHandleColor": 15790320,
"glassColor": 8900331,
"frameWidth": 100,
"frameHeight": 200,
"frameSize": 5,
"frameThickness": 20,
"doorRatio": 0.5,
"openDirection": "RIGHT",
"handleType": "HANDLE_01"
},
"itemType": 7,
"position": [
252.10994952514454,
105,
10
],
"rotation": [
0,
0,
0
],
"scale": [
1,
1,
1
],
"size": [
100,
200,
20
],
"fixed": false,
"resizable": false,
"wall": "4e3d65cb-54c0-0681-28bf-bddcc7bdb571,71d4f128-ae80-3d58-9bd2-711c6ce6cdf2",
"wallSide": "back",
"wallSurfacePoint": [
252.10994952514454,
105,
10
]
},
{
"itemName": "Parametric Door 02",
"isParametric": true,
"baseParametricType": "DOOR",
"subParametricData": {
"type": 5,
"frameColor": 15198183,
"doorColor": 15198183,
"doorHandleColor": 15790320,
"glassColor": 8900331,
"frameWidth": 122,
"frameHeight": 208,
"frameSize": 10.9,
"frameThickness": 20,
"doorRatio": 0.5,
"openDirection": "RIGHT",
"handleType": "HANDLE_01"
},
"itemType": 7,
"position": [
245.9620664305963,
109,
490
],
"rotation": [
0,
3.141592653589793,
0
],
"scale": [
1,
1,
1
],
"size": [
100,
200,
20
],
"fixed": false,
"resizable": false,
"wall": "f90da5e3-9e0e-eba7-173d-eb0b071e838e,da026c08-d76a-a944-8e7b-096b752da9ed",
"wallSide": "back",
"wallSurfacePoint": [
245.9620664305963,
109,
490
]
}
]
}

141
src/blueprint/scripts/tempSrc/empty.json

@ -0,0 +1,141 @@
'{
"floorplan": {
"version": "0.0.2a",
"units": "m",
"corners": {
"71d4f128-ae80-3d58-9bd2-711c6ce6cdf2": {
"x": 0,
"y": 0,
"elevation": 2.5
},
"f90da5e3-9e0e-eba7-173d-eb0b071e838e": {
"x": 0,
"y": 5,
"elevation": 2.5
},
"da026c08-d76a-a944-8e7b-096b752da9ed": {
"x": 5,
"y": 5,
"elevation": 2.5
},
"4e3d65cb-54c0-0681-28bf-bddcc7bdb571": {
"x": 5,
"y": 0,
"elevation": 2.5
}
},
"walls": [{
"corner1": "71d4f128-ae80-3d58-9bd2-711c6ce6cdf2",
"corner2": "f90da5e3-9e0e-eba7-173d-eb0b071e838e",
"frontTexture": {
"url": "rooms/textures/wallmap.png",
"stretch": true,
"scale": 0
},
"backTexture": {
"url": "rooms/textures/wallmap.png",
"stretch": true,
"scale": 0
},
"wallType": "STRAIGHT",
"a": {
"x": -176.77669529663686,
"y": 176.7766952966369
},
"b": {
"x": -176.7766952966369,
"y": 323.22330470336317
}
},
{
"corner1": "f90da5e3-9e0e-eba7-173d-eb0b071e838e",
"corner2": "da026c08-d76a-a944-8e7b-096b752da9ed",
"frontTexture": {
"url": "rooms/textures/wallmap.png",
"stretch": true,
"scale": 0
},
"backTexture": {
"url": "rooms/textures/wallmap.png",
"stretch": true,
"scale": 0
},
"wallType": "STRAIGHT",
"a": {
"x": 176.7766952966369,
"y": 676.7766952966368
},
"b": {
"x": 323.22330470336317,
"y": 676.776695296637
}
},
{
"corner1": "da026c08-d76a-a944-8e7b-096b752da9ed",
"corner2": "4e3d65cb-54c0-0681-28bf-bddcc7bdb571",
"frontTexture": {
"url": "rooms/textures/wallmap.png",
"stretch": true,
"scale": 0
},
"backTexture": {
"url": "rooms/textures/wallmap.png",
"stretch": true,
"scale": 0
},
"wallType": "STRAIGHT",
"a": {
"x": 676.7766952966368,
"y": 323.2233047033631
},
"b": {
"x": 676.776695296637,
"y": 176.77669529663686
}
},
{
"corner1": "4e3d65cb-54c0-0681-28bf-bddcc7bdb571",
"corner2": "71d4f128-ae80-3d58-9bd2-711c6ce6cdf2",
"frontTexture": {
"url": "rooms/textures/wallmap.png",
"stretch": true,
"scale": 0
},
"backTexture": {
"url": "rooms/textures/wallmap.png",
"stretch": true,
"scale": 0
},
"wallType": "STRAIGHT",
"a": {
"x": 323.2233047033631,
"y": -176.77669529663686
},
"b": {
"x": 176.77669529663686,
"y": -176.7766952966369
}
}
],
"rooms": {
"71d4f128-ae80-3d58-9bd2-711c6ce6cdf2,4e3d65cb-54c0-0681-28bf-bddcc7bdb571,da026c08-d76a-a944-8e7b-096b752da9ed,f90da5e3-9e0e-eba7-173d-eb0b071e838e": {
"name": "New Room"
}
},
"wallTextures": [],
"floorTextures": {},
"newFloorTextures": {},
"carbonSheet": {
"url": "",
"transparency": 1,
"x": 0,
"y": 0,
"anchorX": 0,
"anchorY": 0,
"width": 0.01,
"height": 0.01
}
},
"items": [{ "id": "7d0b3e90-c315-e7a5-a6d9-594757d5b7e4", "itemName": "An Item", "itemType": 1, "position": [0, 0, 0], "rotation": [0, 0, 0], "scale": [1, 1, 1], "size": [1, 1, 1], "fixed": true, "resizable": true }];
}
'

176
src/blueprint/scripts/tempSrc/empty_room.json

@ -0,0 +1,176 @@
{
"floorplan": {
"version": "2.0.1a",
"corners": {
"71d4f128-ae80-3d58-9bd2-711c6ce6cdf2": {
"x": 0,
"y": 0,
"elevation": 2.5
},
"f90da5e3-9e0e-eba7-173d-eb0b071e838e": {
"x": 0,
"y": 5,
"elevation": 2.5
},
"da026c08-d76a-a944-8e7b-096b752da9ed": {
"x": 5,
"y": 5,
"elevation": 2.5
},
"4e3d65cb-54c0-0681-28bf-bddcc7bdb571": {
"x": 5,
"y": 0,
"elevation": 2.5
}
},
"walls": [{
"corner1": "71d4f128-ae80-3d58-9bd2-711c6ce6cdf2",
"corner2": "f90da5e3-9e0e-eba7-173d-eb0b071e838e",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png"
},
"backTexture": {
"repeat": 200,
"colormap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_basecolor.jpg",
"bumpmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_height.png",
"normalmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_normal.jpg",
"roughnessmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_roughness.jpg",
"ambientmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_ambientocclusion.jpg",
"color": "#FFFFFF"
},
"wallType": "STRAIGHT",
"a": {
"x": -176.77669529663686,
"y": 176.7766952966369
},
"b": {
"x": -176.7766952966369,
"y": 323.22330470336317
},
"thickness": 0.2
},
{
"corner1": "f90da5e3-9e0e-eba7-173d-eb0b071e838e",
"corner2": "da026c08-d76a-a944-8e7b-096b752da9ed",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png"
},
"backTexture": {
"repeat": 200,
"colormap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_basecolor.jpg",
"bumpmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_height.png",
"normalmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_normal.jpg",
"roughnessmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_roughness.jpg",
"ambientmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_ambientocclusion.jpg",
"color": "#FFFFFF"
},
"wallType": "STRAIGHT",
"a": {
"x": 176.7766952966369,
"y": 676.7766952966368
},
"b": {
"x": 323.22330470336317,
"y": 676.776695296637
},
"thickness": 0.2
},
{
"corner1": "da026c08-d76a-a944-8e7b-096b752da9ed",
"corner2": "4e3d65cb-54c0-0681-28bf-bddcc7bdb571",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png"
},
"backTexture": {
"repeat": 200,
"colormap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_basecolor.jpg",
"bumpmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_height.png",
"normalmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_normal.jpg",
"roughnessmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_roughness.jpg",
"ambientmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_ambientocclusion.jpg",
"color": "#FFFFFF"
},
"wallType": "STRAIGHT",
"a": {
"x": 676.7766952966368,
"y": 323.2233047033631
},
"b": {
"x": 676.776695296637,
"y": 176.77669529663686
},
"thickness": 0.2
},
{
"corner1": "4e3d65cb-54c0-0681-28bf-bddcc7bdb571",
"corner2": "71d4f128-ae80-3d58-9bd2-711c6ce6cdf2",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png"
},
"backTexture": {
"repeat": 200,
"colormap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_basecolor.jpg",
"bumpmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_height.png",
"normalmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_normal.jpg",
"roughnessmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_roughness.jpg",
"ambientmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_ambientocclusion.jpg",
"color": "#FFFFFF"
},
"wallType": "STRAIGHT",
"a": {
"x": 323.2233047033631,
"y": -176.77669529663686
},
"b": {
"x": 176.77669529663686,
"y": -176.7766952966369
},
"thickness": 0.2
}
],
"rooms": {
"71d4f128-ae80-3d58-9bd2-711c6ce6cdf2,4e3d65cb-54c0-0681-28bf-bddcc7bdb571,da026c08-d76a-a944-8e7b-096b752da9ed,f90da5e3-9e0e-eba7-173d-eb0b071e838e": {
"name": "New Room"
}
},
"wallTextures": [],
"floorTextures": {},
"newFloorTextures": {
"4e3d65cb-54c0-0681-28bf-bddcc7bdb571,71d4f128-ae80-3d58-9bd2-711c6ce6cdf2,da026c08-d76a-a944-8e7b-096b752da9ed,f90da5e3-9e0e-eba7-173d-eb0b071e838e": {
"repeat": 100,
"roughnessmap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_roughness.jpg",
"ambientmap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_ambientOcclusion.jpg",
"normalmap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_normal.jpg",
"colormap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_basecolor.jpg",
"color": "#FFFFFF"
}
},
"carbonSheet": {},
"units": "m"
},
"items": []
}

54
src/blueprint/scripts/tempSrc/floor_textures.json

@ -0,0 +1,54 @@
{
"Stylized_Stone_Floor_001": {
"repeat": 100,
"ambientmap": "textures/Floor/Stylized_Stone_Floor_001/Stylized_Stone_Floor_001_ambientOcclusion.jpg",
"normalmap": "textures/Floor/Stylized_Stone_Floor_001/Stylized_Stone_Floor_001_normal.jpg",
"colormap": "textures/Floor/Stylized_Stone_Floor_001/Stylized_Stone_Floor_001_basecolor.jpg",
"roughnessmap": "textures/Floor/Stylized_Stone_Floor_001/Stylized_Stone_Floor_001_roughness.jpg"
},
"Rubber_Floor_001": {
"repeat": 100,
"reflective": 1.0,
"roughnessmap": "textures/Floor/Rubber_Floor_001/Rubber_Floor_001_roughness.jpg",
"colormap": "textures/Floor/Rubber_Floor_001/Rubber_Floor_001_basecolor.jpg",
"ambientmap": "textures/Floor/Rubber_Floor_001/Rubber_Floor_001_ambientOcclusion.jpg",
"normalmap": "textures/Floor/Rubber_Floor_001/Rubber_Floor_001_normal.jpg"
},
"Wood_Herringbone_Tiles_001": {
"repeat": 100,
"ambientmap": "textures/Floor/Wood_Herringbone_Tiles_001/Wood_Herringbone_Tiles_001_ambientOcclusion.jpg",
"colormap": "textures/Floor/Wood_Herringbone_Tiles_001/Wood_Herringbone_Tiles_001_basecolor.jpg",
"normalmap": "textures/Floor/Wood_Herringbone_Tiles_001/Wood_Herringbone_Tiles_001_normal.jpg",
"roughnessmap": "textures/Floor/Wood_Herringbone_Tiles_001/Wood_Herringbone_Tiles_001_roughness.jpg"
},
"Stone_Tiles_004": {
"repeat": 100,
"ambientmap": "textures/Floor/Stone_Tiles_004/Stone_Tiles_004_ambientOcclusion.jpg",
"roughnessmap": "textures/Floor/Stone_Tiles_004/Stone_Tiles_004_roughness.jpg",
"normalmap": "textures/Floor/Stone_Tiles_004/Stone_Tiles_004_normal.jpg",
"colormap": "textures/Floor/Stone_Tiles_004/Stone_Tiles_004_basecolor.jpg"
},
"Terracotta_Tiles_003": {
"repeat": 100,
"reflective": 1.0,
"normalmap": "textures/Floor/Terracotta_Tiles_003/Terracota_Tiles_003_normal.jpg",
"ambientmap": "textures/Floor/Terracotta_Tiles_003/Terracota_Tiles_003_ambientOcclusion.jpg",
"colormap": "textures/Floor/Terracotta_Tiles_003/Terracota_Tiles_003_basecolor.jpg",
"roughnessmap": "textures/Floor/Terracotta_Tiles_003/Terracota_Tiles_003_roughness.jpg"
},
"Marble_Tiles_001": {
"repeat": 100,
"reflective": 0.1,
"ambientmap": "textures/Floor/Marble_Tiles_001/Marble_Tiles_001_ambientOcclusion.jpg",
"colormap": "textures/Floor/Marble_Tiles_001/Marble_Tiles_001_basecolor.jpg",
"roughnessmap": "textures/Floor/Marble_Tiles_001/Marble_Tiles_001_roughness.jpg",
"normalmap": "textures/Floor/Marble_Tiles_001/Marble_Tiles_001_normal.jpg"
},
"Terrazzo_Tiles_001": {
"repeat": 100,
"roughnessmap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_roughness.jpg",
"ambientmap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_ambientOcclusion.jpg",
"normalmap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_normal.jpg",
"colormap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_basecolor.jpg"
}
}

537
src/blueprint/scripts/tempSrc/index.js

@ -0,0 +1,537 @@
import JSZip from "jszip";
import FileSaver from 'file-saver';
import FPS from 'fps-now';
import { BlueprintJS } from './scripts/blueprint.js';
import { EVENT_LOADED, EVENT_NOTHING_2D_SELECTED, EVENT_CORNER_2D_CLICKED, EVENT_WALL_2D_CLICKED, EVENT_ROOM_2D_CLICKED, EVENT_WALL_CLICKED, EVENT_ROOM_CLICKED, EVENT_NO_ITEM_SELECTED, EVENT_ITEM_SELECTED, EVENT_GLTF_READY } from './scripts/core/events.js';
import { Configuration, configDimUnit, viewBounds } from './scripts/core/configuration.js';
import { dimMeter, TEXTURE_NO_PREVIEW } from './scripts/core/constants.js';
import QuickSettings from 'quicksettings';
import { Dimensioning } from './scripts/core/dimensioning.js';
import { ParametricsInterface } from './scripts/ParametricsInterface.js';
import * as floor_textures_json from './floor_textures.json';
import * as wall_textures_json from './wall_textures.json';
// import * as default_room_json from './parametrics_items.json';
// import * as default_room_json from './empty_room.json';
import * as default_room_json from './designWithBoundary.json';
// import * as default_room_json from './designWithoutBoundary.json';
// import * as default_room_json from './LShape.json';
const fps = FPS.of({x: 0, y: 0});
fps.start();
let default_room = JSON.stringify(default_room_json);
let startY = 0;
let panelWidths = 200;
let uxInterfaceHeight = 450;
let subPanelsHeight = 460;
let floor_textures = floor_textures_json['default'];
let floor_texture_keys = Object.keys(floor_textures);
let wall_textures = wall_textures_json['default'];
let wall_texture_keys = Object.keys(wall_textures);
let blueprint3d = null;
let app_parent = document.getElementById('bp3d-js-app');
let configurationHelper = null;
let floorplanningHelper = null;
let roomplanningHelper = null;
let settingsViewer2d = null;
let settingsSelectedCorner = null;
let settingsSelectedWall = null;
let settingsSelectedRoom = null;
let settingsSelectedRoom3D = null;
let settingsSelectedWall3D = null;
let settingsViewer3d = null;
let uxInterface = null;
let parametricContextInterface = null;
let doorsData = {
'Door Type 1': { src: 'assets/doors/DoorType1.png', type: 1 },
'Door Type 2': { src: 'assets/doors/DoorType2.png', type: 2 },
'Door Type 3': { src: 'assets/doors/DoorType3.png', type: 3 },
'Door Type 4': { src: 'assets/doors/DoorType4.png', type: 4 },
'Door Type 5': { src: 'assets/doors/DoorType5.png', type: 5 },
'Door Type 6': { src: 'assets/doors/DoorType6.png', type: 6 },
};
let doorTypes = Object.keys(doorsData);
let opts = {
viewer2d: {
id: 'bp3djs-viewer2d',
viewer2dOptions: {
'corner-radius': 12.5,
'boundary-point-radius': 5.0,
'boundary-line-thickness': 2.0,
'boundary-point-color':'#030303',
'boundary-line-color':'#090909',
pannable: true,
zoomable: true,
scale: false,
rotate: true,
translate: true,
dimlinecolor: '#3E0000',
dimarrowcolor: '#FF0000',
dimtextcolor: '#000000',
pixiAppOptions: {
resolution: 1,
},
pixiViewportOptions: {
passiveWheel: false,
}
},
},
viewer3d: {
id: 'bp3djs-viewer3d',
viewer3dOptions:{
occludedWalls: false,
occludedRoofs: false
}
},
textureDir: "models/textures/",
widget: false,
resize: true,
};
function selectFloorTexture(data) {
if (!data.index) {
data = settingsSelectedRoom3D.getValue('Floor Textures');
}
let floor_texture_pack = floor_textures[data.value];
if(floor_texture_pack.colormap){
settingsSelectedRoom3D.setValue('Floor Texture:', floor_texture_pack.colormap);
}
else{
settingsSelectedRoom3D.setValue('Floor Texture:', TEXTURE_NO_PREVIEW);
}
roomplanningHelper.roomTexturePack = floor_texture_pack;
}
function selectWallTexture(data) {
if (!data.index) {
if (settingsSelectedWall3D._hidden && !settingsSelectedRoom3D._hidden) {
data = settingsSelectedRoom3D.getValue('All Wall Textures');
} else {
data = settingsSelectedWall3D.getValue('Wall Textures');
}
}
let wall_texture_pack = wall_textures[data.value];
let colormap = wall_texture_pack.colormap;
if (settingsSelectedWall3D._hidden && !settingsSelectedRoom3D._hidden) {
if(colormap){
settingsSelectedRoom3D.setValue('All Wall Texture:', colormap);
}
else{
settingsSelectedRoom3D.setValue('All Wall Texture:', TEXTURE_NO_PREVIEW);
}
roomplanningHelper.roomWallsTexturePack = wall_texture_pack;
} else {
if(colormap){
settingsSelectedWall3D.setValue('Wall Texture:', wall_texture_pack.colormap);
}
else{
settingsSelectedWall3D.setValue('Wall Texture:', TEXTURE_NO_PREVIEW);
}
roomplanningHelper.wallTexturePack = wall_texture_pack;
}
}
function selectFloorTextureColor(data) {
roomplanningHelper.setRoomFloorColor(data);
}
function selectWallTextureColor(data) {
if (settingsSelectedWall3D._hidden && !settingsSelectedRoom3D._hidden) {
roomplanningHelper.setRoomWallsTextureColor(data);
}
else {
roomplanningHelper.setWallColor(data);
}
}
function selectDoorForWall(data) {
if (!data.index) {
data = settingsSelectedWall3D.getValue('Select Door');
}
let selectedDoor = doorsData[data.value];
settingsSelectedWall3D.setValue('Door Preview:', selectedDoor.src);
}
function addDoorForWall() {
let data = settingsSelectedWall3D.getValue('Select Door');
let selectedDoor = doorsData[data.value];
roomplanningHelper.addParametricDoorToCurrentWall(selectedDoor.type);
}
function switchViewer() {
blueprint3d.switchView();
if (blueprint3d.currentView === 2) {
uxInterface.setValue("Current View", "Floor Planning");
settingsViewer3d.hide();
settingsViewer2d.show();
settingsSelectedWall3D.hide();
settingsSelectedRoom3D.hide();
if (parametricContextInterface) {
parametricContextInterface.destroy();
parametricContextInterface = null;
}
} else if (blueprint3d.currentView === 3) {
uxInterface.setValue("Current View", "Room Planning");
settingsViewer2d.hide();
settingsSelectedCorner.hide();
settingsSelectedWall.hide();
settingsSelectedRoom.hide();
settingsViewer3d.show();
}
}
function switchViewer2DToDraw() {
blueprint3d.setViewer2DModeToDraw();
}
function switchViewer2DToMove() {
blueprint3d.setViewer2DModeToMove();
}
function switchViewer2DToTransform() {
blueprint3d.switchViewer2DToTransform();
}
function loadBlueprint3DDesign(filedata) {
let reader = new FileReader();
reader.onload = function(event) {
let data = event.target.result;
blueprint3d.model.loadSerialized(data);
};
reader.readAsText(filedata);
}
function loadLockedBlueprint3DDesign(filedata) {
let reader = new FileReader();
reader.onload = function(event) {
let data = event.target.result;
blueprint3d.model.loadLockedSerialized(data);
};
reader.readAsText(filedata);
}
function saveBlueprint3DDesign() {
let data = blueprint3d.model.exportSerialized();
let a = window.document.createElement('a');
let blob = new Blob([data], { type: 'text' });
a.href = window.URL.createObjectURL(blob);
a.download = 'design.blueprint3d';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
function saveBlueprint3D() {
blueprint3d.roomplanner.exportSceneAsGTLF();
}
function exportDesignAsPackage() {
function getWallTextureImages(texobject, pre_image_paths) {
let image_paths = [];
if (!texobject) {
return image_paths;
}
if (texobject.normalmap && !pre_image_paths.includes(texobject.normalmap)) {
image_paths.push(texobject.normalmap);
}
if (texobject.colormap && !pre_image_paths.includes(texobject.colormap)) {
image_paths.push(texobject.colormap);
}
if (texobject.roughnessmap && !pre_image_paths.includes(texobject.roughnessmap)) {
image_paths.push(texobject.roughnessmap);
}
if (texobject.ambientmap && !pre_image_paths.includes(texobject.ambientmap)) {
image_paths.push(texobject.ambientmap);
}
if (texobject.bumpmap && !pre_image_paths.includes(texobject.bumpmap)) {
image_paths.push(texobject.bumpmap);
}
return image_paths;
}
let designFile = blueprint3d.model.exportSerialized();
let jsonDesignFile = JSON.parse(designFile);
let floorplan = jsonDesignFile.floorplan;
let items = jsonDesignFile.items;
let images = [];
let models = [];
let i = 0;
for (i = 0; i < floorplan.walls.length; i++) {
let wall = floorplan.walls[i];
images = images.concat(getWallTextureImages(wall.frontTexture, images));
images = images.concat(getWallTextureImages(wall.backTexture, images));
}
Object.values(floorplan.newFloorTextures).forEach((texturePack) => {
images = images.concat(getWallTextureImages(texturePack, images));
console.log("TEXTURE PACK ", texturePack);
});
// for (i = 0; i < floorplan.newFloorTextures.length; i++) {
// let roomTexture = floorplan.newFloorTextures[i];
// console.log(roomTexture);
// }
for (i = 0; i < items.length; i++) {
let item = items[i];
if (!item.isParametric && !models.includes(item.modelURL)) {
models.push(item.modelURL);
}
}
let fetched_image_files = [];
let fetched_model_files = [];
function writeZip() {
if (!fetched_image_files.length === images.length && !fetched_model_files.length === models.length) {
return;
}
}
let zip = new JSZip();
zip.file('design.blueprint3d', designFile);
//Adding the zip files from an url
//Taken from https://medium.com/@joshmarinacci/a-little-fun-with-zip-files-4058812abf92
for (i = 0; i < images.length; i++) {
let image_path = images[i];
const imageBlob = fetch(image_path).then(response => {
if (response.status === 200) {
return response.blob();
}
return Promise.reject(new Error(response.statusText));
});
zip.file(image_path, imageBlob); //, { base64: false }); //, { base64: true }
}
for (i = 0; i < models.length; i++) {
let model_path = models[i];
const gltfBlob = fetch(model_path).then(response => {
if (response.status === 200) {
return response.blob();
}
return Promise.reject(new Error(response.statusText));
});
zip.file(model_path, gltfBlob); //, { base64: false }); //, { base64: true }
}
zip.generateAsync({ type: "blob" }).then(function(content) {
FileSaver.saveAs(content, "YourBlueprintProject.zip");
});
// let a = window.document.createElement('a');
// let blob = new Blob([zip.toBuffer()], { type: 'octet/stream' });
// a.href = window.URL.createObjectURL(blob);
// a.download = 'YourBlueprintProject.zip';
// document.body.appendChild(a);
// a.click();
// document.body.removeChild(a);
}
// document.addEventListener('DOMContentLoaded', function() {
console.log('ON DOCUMENT READY ');
Configuration.setValue(viewBounds, 10000);//In CMS
blueprint3d = new BlueprintJS(opts);
Configuration.setValue(configDimUnit, dimMeter);
configurationHelper = blueprint3d.configurationHelper;
floorplanningHelper = blueprint3d.floorplanningHelper;
roomplanningHelper = blueprint3d.roomplanningHelper;
blueprint3d.model.addEventListener(EVENT_LOADED, function() { console.log('LOAD SERIALIZED JSON ::: '); });
blueprint3d.floorplanner.addFloorplanListener(EVENT_NOTHING_2D_SELECTED, function() {
settingsSelectedCorner.hide();
settingsSelectedWall.hide();
settingsSelectedRoom.hide();
settingsViewer2d.hideControl('Delete');
});
blueprint3d.floorplanner.addFloorplanListener(EVENT_CORNER_2D_CLICKED, function(evt) {
settingsSelectedCorner.show();
settingsSelectedWall.hide();
settingsSelectedRoom.hide();
settingsViewer2d.showControl('Delete');
settingsSelectedCorner.setValue('cornerElevation', Dimensioning.cmToMeasureRaw(evt.item.elevation));
});
blueprint3d.floorplanner.addFloorplanListener(EVENT_WALL_2D_CLICKED, function(evt) {
settingsSelectedCorner.hide();
settingsSelectedWall.show();
settingsSelectedRoom.hide();
settingsViewer2d.showControl('Delete');
settingsSelectedWall.setValue('wallThickness', Dimensioning.cmToMeasureRaw(evt.item.thickness));
});
blueprint3d.floorplanner.addFloorplanListener(EVENT_ROOM_2D_CLICKED, function(evt) {
settingsSelectedCorner.hide();
settingsSelectedWall.hide();
settingsSelectedRoom.show();
settingsSelectedRoom.setValue('roomName', evt.item.name);
});
blueprint3d.roomplanner.addRoomplanListener(EVENT_ITEM_SELECTED, function(evt) {
settingsSelectedWall3D.hide();
settingsSelectedRoom3D.hide();
let itemModel = evt.itemModel;
if (parametricContextInterface) {
parametricContextInterface.destroy();
parametricContextInterface = null;
}
if (itemModel.isParametric) {
parametricContextInterface = new ParametricsInterface(itemModel.parametricClass, blueprint3d.roomplanner);
}
});
blueprint3d.roomplanner.addRoomplanListener(EVENT_NO_ITEM_SELECTED, function() {
settingsSelectedWall3D.hide();
settingsSelectedRoom3D.hide();
if (parametricContextInterface) {
parametricContextInterface.destroy();
parametricContextInterface = null;
}
});
blueprint3d.roomplanner.addRoomplanListener(EVENT_WALL_CLICKED, function(evt) {
settingsSelectedWall3D.show();
settingsSelectedRoom3D.hide();
if (parametricContextInterface) {
parametricContextInterface.destroy();
parametricContextInterface = null;
}
});
blueprint3d.roomplanner.addRoomplanListener(EVENT_ROOM_CLICKED, function(evt) {
settingsSelectedWall3D.hide();
settingsSelectedRoom3D.show();
if (parametricContextInterface) {
parametricContextInterface.destroy();
parametricContextInterface = null;
}
});
blueprint3d.roomplanner.addRoomplanListener(EVENT_GLTF_READY, function(evt) {
let data = evt.gltf;
let a = window.document.createElement('a');
let blob = new Blob([data], { type: 'text' });
a.href = window.URL.createObjectURL(blob);
a.download = 'design.gltf';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
});
// console.log(default_room);
blueprint3d.model.loadSerialized(default_room);
if (!opts.widget) {
uxInterface = QuickSettings.create(0, 0, 'BlueprintJS', app_parent);
settingsViewer2d = QuickSettings.create(0, 0, 'Viewer 2D', app_parent);
settingsSelectedCorner = QuickSettings.create(0, 0, 'Corner', app_parent);
settingsSelectedWall = QuickSettings.create(0, 0, 'Wall', app_parent);
settingsSelectedRoom = QuickSettings.create(0, 0, 'Room', app_parent);
settingsViewer3d = QuickSettings.create(0, 0, 'Viewer 3D', app_parent);
settingsSelectedWall3D = QuickSettings.create(0, 0, 'Wall', app_parent);
settingsSelectedRoom3D = QuickSettings.create(0, 0, 'Room', app_parent);
uxInterface.addButton('Switch Viewer', switchViewer);
uxInterface.addHTML('Current View', 'Floorplanning');
uxInterface.addFileChooser("Load Design", "Load Design", ".blueprint3d", loadBlueprint3DDesign);
uxInterface.addButton('Save Design', saveBlueprint3DDesign);
uxInterface.addButton('Export as GLTF', saveBlueprint3D);
uxInterface.addButton('Export Project (blueprint-py)', exportDesignAsPackage);
uxInterface.addButton('Reset', blueprint3d.model.reset.bind(blueprint3d.model));
uxInterface.addFileChooser("Load Locked Design", "Load Locked Design", ".blueprint3d", loadLockedBlueprint3DDesign);
settingsViewer2d.addButton('Draw Mode', switchViewer2DToDraw);
settingsViewer2d.addButton('Move Mode', switchViewer2DToMove);
settingsViewer2d.addButton('Transform Mode', switchViewer2DToTransform);
settingsViewer2d.addButton('Delete', floorplanningHelper.deleteCurrentItem.bind(floorplanningHelper));
settingsViewer2d.bindBoolean('snapToGrid', configurationHelper.snapToGrid, configurationHelper);
settingsViewer2d.bindBoolean('directionalDrag', configurationHelper.directionalDrag, configurationHelper);
settingsViewer2d.bindBoolean('dragOnlyX', configurationHelper.dragOnlyX, configurationHelper);
settingsViewer2d.bindBoolean('dragOnlyY', configurationHelper.dragOnlyY, configurationHelper);
settingsViewer2d.bindRange('snapTolerance', 1, 200, configurationHelper.snapTolerance, 1, configurationHelper);
settingsViewer2d.bindRange('gridSpacing', 10, 200, configurationHelper.gridSpacing, 1, configurationHelper);
settingsViewer2d.bindNumber('boundsX', 1, 200, configurationHelper.boundsX, 1, configurationHelper);
settingsViewer2d.bindNumber('boundsY', 1, 200, configurationHelper.boundsY, 1, configurationHelper);
settingsSelectedCorner.bindRange('cornerElevation', 1, 500, floorplanningHelper.cornerElevation, 1, floorplanningHelper);
settingsSelectedWall.bindRange('wallThickness', 0.01, 1, floorplanningHelper.wallThickness, 0.01, floorplanningHelper);
settingsSelectedRoom.bindText('roomName', floorplanningHelper.roomName, floorplanningHelper);
// settingsViewer3d.addDropDown('Floor Textures', floor_texture_keys, selectFloorTexture);
// settingsViewer3d.addImage('Floor Texture:', floor_textures[floor_texture_keys[0]].colormap, null);
// settingsViewer3d.addButton('Apply', selectFloorTexture);
// settingsViewer3d.addDropDown('Wall Textures', wall_texture_keys, selectWallTexture);
// settingsViewer3d.addImage('Wall Texture:', wall_textures[wall_texture_keys[0]].colormap, null);
// settingsViewer3d.addButton('Apply', selectWallTexture);
settingsSelectedRoom3D.addDropDown('Floor Textures', floor_texture_keys, selectFloorTexture);
settingsSelectedRoom3D.addImage('Floor Texture:', floor_textures[floor_texture_keys[0]].colormap || TEXTURE_NO_PREVIEW, null);
settingsSelectedRoom3D.addColor('Floor Texture Color:', floor_textures[floor_texture_keys[0]].color || '#FFFFFF', selectFloorTextureColor);
settingsSelectedRoom3D.addButton('Apply', selectFloorTexture);
settingsSelectedRoom3D.addDropDown('All Wall Textures', wall_texture_keys, selectWallTexture);
settingsSelectedRoom3D.addImage('All Wall Texture:', wall_textures[wall_texture_keys[0]].colormap || TEXTURE_NO_PREVIEW, selectWallTexture);
settingsSelectedRoom3D.addColor('All Wall Texture Color:', wall_textures[wall_texture_keys[0]].color || '#FFFFFF', selectWallTextureColor);
settingsSelectedRoom3D.addButton('Apply', selectWallTexture);
settingsSelectedWall3D.addDropDown('Wall Textures', wall_texture_keys, selectWallTexture);
settingsSelectedWall3D.addImage('Wall Texture:', wall_textures[wall_texture_keys[0]].colormap || TEXTURE_NO_PREVIEW, null);
settingsSelectedWall3D.addColor('Wall Texture Color:', wall_textures[wall_texture_keys[0]].color || '#FFFFFF', selectWallTextureColor);
settingsSelectedWall3D.addButton('Apply', selectWallTexture);
settingsSelectedWall3D.addDropDown('Select Door', doorTypes, selectDoorForWall);
settingsSelectedWall3D.addImage('Door Preview:', doorsData[doorTypes[0]].src, null);
settingsSelectedWall3D.addButton('Add', addDoorForWall);
settingsViewer3d.addHTML('Tips:', '<p>Click and drag to rotate the room in 360\xB0</p><p>Add room items <ul><li>Add parametric doors</li><li>Other items (Coming soon)</li></ul></p><p>Drag and Place items(pink boxes and parametric doors) in the room</p><p>There are 8 different types of items <ul><li>1: FloorItem</li> <li>2: WallItem</li> <li>3: InWallItem</li> <li>7: InWallFloorItem</li> <li>8: OnFloorItem</li> <li>9: WallFloorItem</li><li>0: Item</li> <li>4: RoofItem</li></ul></p>');
uxInterface.setWidth(panelWidths);
uxInterface.setHeight(uxInterfaceHeight);
settingsViewer2d.hideControl('Delete');
settingsViewer2d.setWidth(panelWidths);
settingsViewer3d.setWidth(panelWidths);
settingsViewer2d.setHeight(subPanelsHeight);
settingsViewer3d.setHeight(subPanelsHeight);
uxInterface.setPosition(app_parent.clientWidth - panelWidths, startY);
settingsViewer2d.setPosition(app_parent.clientWidth - panelWidths, startY + uxInterfaceHeight);
settingsViewer3d.setPosition(app_parent.clientWidth - panelWidths, startY + uxInterfaceHeight);
settingsSelectedCorner.hide();
settingsSelectedWall.hide();
settingsSelectedRoom.hide();
settingsViewer3d.hide();
settingsSelectedWall3D.hide();
settingsSelectedRoom3D.hide();
}

366
src/blueprint/scripts/tempSrc/parametrics_items.json

@ -0,0 +1,366 @@
{
"floorplan": {
"version": "2.0.1a",
"corners": {
"71d4f128-ae80-3d58-9bd2-711c6ce6cdf2": {
"x": 0,
"y": 0,
"elevation": 2.5
},
"f90da5e3-9e0e-eba7-173d-eb0b071e838e": {
"x": 0,
"y": 5,
"elevation": 2.5
},
"da026c08-d76a-a944-8e7b-096b752da9ed": {
"x": 5,
"y": 5,
"elevation": 2.5
},
"4e3d65cb-54c0-0681-28bf-bddcc7bdb571": {
"x": 5,
"y": 0,
"elevation": 2.5
}
},
"walls": [{
"corner1": "71d4f128-ae80-3d58-9bd2-711c6ce6cdf2",
"corner2": "f90da5e3-9e0e-eba7-173d-eb0b071e838e",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png"
},
"backTexture": {
"repeat": 200,
"colormap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_basecolor.jpg",
"bumpmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_height.png",
"normalmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_normal.jpg",
"roughnessmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_roughness.jpg",
"ambientmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_ambientocclusion.jpg",
"color": "#FFFFFF"
},
"wallType": "STRAIGHT",
"a": {
"x": -176.77669529663686,
"y": 176.7766952966369
},
"b": {
"x": -176.7766952966369,
"y": 323.22330470336317
},
"thickness": 0.2
},
{
"corner1": "f90da5e3-9e0e-eba7-173d-eb0b071e838e",
"corner2": "da026c08-d76a-a944-8e7b-096b752da9ed",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png"
},
"backTexture": {
"repeat": 200,
"colormap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_basecolor.jpg",
"bumpmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_height.png",
"normalmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_normal.jpg",
"roughnessmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_roughness.jpg",
"ambientmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_ambientocclusion.jpg",
"color": "#FFFFFF"
},
"wallType": "STRAIGHT",
"a": {
"x": 176.7766952966369,
"y": 676.7766952966368
},
"b": {
"x": 323.22330470336317,
"y": 676.776695296637
},
"thickness": 0.2
},
{
"corner1": "da026c08-d76a-a944-8e7b-096b752da9ed",
"corner2": "4e3d65cb-54c0-0681-28bf-bddcc7bdb571",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png"
},
"backTexture": {
"repeat": 200,
"colormap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_basecolor.jpg",
"bumpmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_height.png",
"normalmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_normal.jpg",
"roughnessmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_roughness.jpg",
"ambientmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_ambientocclusion.jpg",
"color": "#FFFFFF"
},
"wallType": "STRAIGHT",
"a": {
"x": 676.7766952966368,
"y": 323.2233047033631
},
"b": {
"x": 676.776695296637,
"y": 176.77669529663686
},
"thickness": 0.2
},
{
"corner1": "4e3d65cb-54c0-0681-28bf-bddcc7bdb571",
"corner2": "71d4f128-ae80-3d58-9bd2-711c6ce6cdf2",
"frontTexture": {
"color": "#FFFFFF",
"repeat": 300,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png"
},
"backTexture": {
"repeat": 200,
"colormap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_basecolor.jpg",
"bumpmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_height.png",
"normalmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_normal.jpg",
"roughnessmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_roughness.jpg",
"ambientmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_ambientocclusion.jpg",
"color": "#FFFFFF"
},
"wallType": "STRAIGHT",
"a": {
"x": 323.2233047033631,
"y": -176.77669529663686
},
"b": {
"x": 176.77669529663686,
"y": -176.7766952966369
},
"thickness": 0.2
}
],
"rooms": {
"71d4f128-ae80-3d58-9bd2-711c6ce6cdf2,4e3d65cb-54c0-0681-28bf-bddcc7bdb571,da026c08-d76a-a944-8e7b-096b752da9ed,f90da5e3-9e0e-eba7-173d-eb0b071e838e": {
"name": "Ashok's Room"
}
},
"wallTextures": [],
"floorTextures": {},
"newFloorTextures": {
"4e3d65cb-54c0-0681-28bf-bddcc7bdb571,71d4f128-ae80-3d58-9bd2-711c6ce6cdf2,da026c08-d76a-a944-8e7b-096b752da9ed,f90da5e3-9e0e-eba7-173d-eb0b071e838e": {
"repeat": 100,
"roughnessmap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_roughness.jpg",
"ambientmap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_ambientOcclusion.jpg",
"normalmap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_normal.jpg",
"colormap": "textures/Floor/Terrazzo_Tiles_001/Terrazzo_Tiles_001_basecolor.jpg",
"color": "#FFFFFF"
}
},
"carbonSheet": {},
"units": "m"
},
"items": [{
"id": "7d0b3e90-c315-e7a5-a6d9-594757d5b7e4",
"itemName": "An Item",
"itemType": 3,
"position": [
10,
138.38790186348007,
185.34460161835352
],
"rotation": [
0,
1.5707963267948966,
0
],
"scale": [
1,
1,
1
],
"size": [
240,
100,
50
],
"fixed": true,
"resizable": true,
"modelURL": "models/HollowCube.glb",
"isParametric": false,
"wall": "71d4f128-ae80-3d58-9bd2-711c6ce6cdf2,f90da5e3-9e0e-eba7-173d-eb0b071e838e",
"wallSide": "back",
"wallSurfacePoint": [
10,
138.38790186348007,
185.34460161835352
],
},
{
"itemName": "Tennis Table",
"itemType": 1,
"position": [
209.43984621295914,
49.05,
270.9912269855666
],
"rotation": [
0,
0,
0
],
"scale": [
1,
1,
1
],
"size": [
281.598,
98.1,
172.4
],
"fixed": false,
"resizable": false,
"modelURL": "models/TableTennisTable.glb",
"isParametric": false
},
{
"itemName": "DoubleChairWithPillow",
"itemType": 9,
"position": [
209.43984621295914,
49.05,
270.9912269855666
],
"rotation": [
0,
0,
0
],
"scale": [
1,
1,
1
],
"size": [
108.85,
72.7337,
69.2864
],
"fixed": false,
"resizable": false,
"modelURL": "models/DoubleChairWithPillow.glb",
"isParametric": false
},
{
"itemName": "Parametric Door 01",
"isParametric": true,
"baseParametricType": "DOOR",
"subParametricData": {
"type": 6,
"frameColor": 15198183,
"doorColor": 15198183,
"doorHandleColor": 15790320,
"glassColor": 8900331,
"frameWidth": 100,
"frameHeight": 200,
"frameSize": 5,
"frameThickness": 20,
"doorRatio": 0.5,
"openDirection": "RIGHT",
"handleType": "HANDLE_01"
},
"itemType": 7,
"position": [
252.10994952514463,
105,
10
],
"rotation": [
0,
0,
0
],
"scale": [
1,
1,
1
],
"size": [
100,
200,
20
],
"fixed": false,
"resizable": false,
"wall": "4e3d65cb-54c0-0681-28bf-bddcc7bdb571,71d4f128-ae80-3d58-9bd2-711c6ce6cdf2",
"wallSide": "back",
"wallSurfacePoint": [
252.10994952514463,
105,
10
],
},
{
"itemName": "Parametric Door 02",
"isParametric": true,
"baseParametricType": "DOOR",
"subParametricData": {
"type": 5,
"frameColor": 15198183,
"doorColor": 15198183,
"doorHandleColor": 15790320,
"glassColor": 8900331,
"frameWidth": 122,
"frameHeight": 208,
"frameSize": 10.9,
"frameThickness": 20,
"doorRatio": 0.5,
"openDirection": "RIGHT",
"handleType": "HANDLE_01"
},
"itemType": 7,
"position": [
245.9620664305963,
109,
490
],
"rotation": [
0,
3.141592653589793,
0
],
"scale": [
1,
1,
1
],
"size": [
100,
200,
20
],
"fixed": false,
"resizable": false,
"wall": "f90da5e3-9e0e-eba7-173d-eb0b071e838e,da026c08-d76a-a944-8e7b-096b752da9ed",
"wallSide": "back",
"wallSurfacePoint": [
245.9620664305963,
109,
490
]
}
]
}

81
src/blueprint/scripts/tempSrc/wall_textures.json

@ -0,0 +1,81 @@
{
"Plain_White_Wall_001": {
"repeat": 200,
"color": "#FFFFFF",
"normalmap": "textures/Wall/Stone-Wall-015/Wall_Stone_015_normal.jpg",
"ambientmap": "textures/Wall/Stone-Wall-015/Wall_Stone_015_ambientOcclusion.jpg",
"roughnessmap": "textures/Wall/Stone-Wall-015/Wall_Stone_015_roughness.jpg"
},
"Concrete_Wall_005_SD": {
"repeat": 200,
"colormap": "textures/Wall/Concrete_Wall_005_SD/Concrete_Wall_005_BaseColor.jpg",
"normalmap": "textures/Wall/Concrete_Wall_005_SD/Concrete_Wall_005_Normal.jpg",
"bumpmap": "textures/Wall/Concrete_Wall_005_SD/Concrete_Wall_005_Height.png",
"ambientmap": "textures/Wall/Concrete_Wall_005_SD/Concrete_Wall_005_AmbientOcclusion.jpg",
"roughnessmap": "textures/Wall/Concrete_Wall_005_SD/Concrete_Wall_005_Roughness.jpg"
},
"Terracotta_Bricks_002": {
"repeat": 200,
"normalmap": "textures/Wall/Terracotta_Bricks_002/Bricks_Terracotta_002_normal.jpg",
"ambientmap": "textures/Wall/Terracotta_Bricks_002/Bricks_Terracotta_002_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Terracotta_Bricks_002/Bricks_Terracotta_002_height.png",
"roughnessmap": "textures/Wall/Terracotta_Bricks_002/Bricks_Terracotta_002_roughness.jpg",
"colormap": "textures/Wall/Terracotta_Bricks_002/Bricks_Terracotta_002_basecolor.jpg"
},
"Concrete-Wall-002": {
"repeat": 200,
"colormap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_basecolor.jpg",
"bumpmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_height.png",
"normalmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_normal.jpg",
"roughnessmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_roughness.jpg",
"ambientmap": "textures/Wall/Concrete-Wall-002/Concrete_Wall_002_ambientocclusion.jpg"
},
"Concrete_016_SD": {
"repeat": 200,
"bumpmap": "textures/Wall/Concrete_016_SD/Concrete_016_height.png",
"ambientmap": "textures/Wall/Concrete_016_SD/Concrete_016_ambientOcclusion.jpg",
"normalmap": "textures/Wall/Concrete_016_SD/Concrete_016_normal.jpg",
"roughnessmap": "textures/Wall/Concrete_016_SD/Concrete_016_roughness.jpg",
"colormap": "textures/Wall/Concrete_016_SD/Concrete_016_baseColor.jpg"
},
"Concrete_Column_001_SD": {
"repeat": 200,
"ambientmap": "textures/Wall/Concrete_Column_001_SD/Concrete_Column_001_ambientOcclusion.jpg",
"normalmap": "textures/Wall/Concrete_Column_001_SD/Concrete_Column_001_normal.jpg",
"bumpmap": "textures/Wall/Concrete_Column_001_SD/Concrete_Column_001_height.png",
"roughnessmap": "textures/Wall/Concrete_Column_001_SD/Concrete_Column_001_roughness.jpg",
"colormap": "textures/Wall/Concrete_Column_001_SD/Concrete_Column_001_basecolor.jpg"
},
"Brick_Wall_017_SD": {
"repeat": 200,
"normalmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg",
"roughnessmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg",
"colormap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg",
"ambientmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png"
},
"Stone-Wall-015": {
"repeat": 200,
"colormap": "textures/Wall/Stone-Wall-015/Wall_Stone_015_basecolor.jpg",
"normalmap": "textures/Wall/Stone-Wall-015/Wall_Stone_015_normal.jpg",
"ambientmap": "textures/Wall/Stone-Wall-015/Wall_Stone_015_ambientOcclusion.jpg",
"bumpmap": "textures/Wall/Stone-Wall-015/Wall_Stone_015_height.png",
"roughnessmap": "textures/Wall/Stone-Wall-015/Wall_Stone_015_roughness.jpg"
},
"Stone_Wall_012_SD": {
"repeat": 200,
"ambientmap": "textures/Wall/Stone_Wall_012_SD/Stone_Wall_ambientOcclusion.jpg",
"colormap": "textures/Wall/Stone_Wall_012_SD/Stone_Wall_basecolor.jpg",
"normalmap": "textures/Wall/Stone_Wall_012_SD/Stone_Wall_normal.jpg",
"bumpmap": "textures/Wall/Stone_Wall_012_SD/Stone_Wall_height.png",
"roughnessmap": "textures/Wall/Stone_Wall_012_SD/Stone_Wall_roughness.jpg"
},
"Stylized-Sci-fi Wall-001": {
"repeat": 125,
"normalmap": "textures/Wall/Stylized-Sci-fi Wall-001/Stylized_Sci-fi_Wall_001_normal.jpg",
"ambientmap": "textures/Wall/Stylized-Sci-fi Wall-001/Stylized_Sci-fi_Wall_001_ambientOcclusion.jpg",
"colormap": "textures/Wall/Stylized-Sci-fi Wall-001/Stylized_Sci-fi_Wall_001_basecolor.jpg",
"roughnessmap": "textures/Wall/Stylized-Sci-fi Wall-001/Stylized_Sci-fi_Wall_001_roughness.jpg",
"bumpmap": "textures/Wall/Stylized-Sci-fi Wall-001/Stylized_Sci-fi_Wall_001_height.png"
}
}

203
src/blueprint/scripts/viewer2d/BaseFloorplanViewElement2D.ts

@ -0,0 +1,203 @@
import { Graphics } from 'pixi.js';
import { Dimensioning } from '../core/dimensioning';
import { Floorplan } from '../model/floorplan';
import { EventSystem } from '../core/EventSystem';
import { Vector2 } from 'babylonjs';
export class BaseFloorplanViewElement2D extends Graphics {
__floorplan;
__options;
__interactable;
__isDragging;
__isSelected;
__snapToGrid;
__keyboard;
__mouseDownEvent;
__mouseUpEvent;
__mouseMoveEvent;
__mouseOverEvent;
__mouseOutEvent;
__mouseClickEvent;
__keyListenerEvent;
constructor(floorplan: Floorplan, options: any) {
super();
this.__floorplan = floorplan;
this.__options = {};
for (let opt in options) {
this.__options[opt] = options[opt];
}
// this.__eventDispatcher = new EventDispatcher();
this.__interactable = true;
this.interactive = true;
this.buttonMode = true;
this.__isDragging = false;
this.__isSelected = false;
this.__snapToGrid = false;
// this.__keyboard = new KeyboardListener2D();// 按键管理现在不需要创建
this.__mouseDownEvent = this.__dragStart.bind(this);
this.__mouseUpEvent = this.__dragEnd.bind(this);
this.__mouseMoveEvent = this.__dragMove.bind(this);
this.__mouseOverEvent = this.__mouseOver.bind(this);
this.__mouseOutEvent = this.__mouseOut.bind(this);
this.__mouseClickEvent = this.__click.bind(this);
this.__keyListenerEvent = this.__keyListener.bind(this);
this.on('mousedown', this.__mouseClickEvent).on('touchstart', this.__mouseClickEvent);
this.on('mouseupoutside', this.__mouseUpEvent).on('touchendoutside', this.__mouseUpEvent);
this.on('mouseup', this.__mouseUpEvent).on('touchend', this.__mouseUpEvent);
this.on('mousemove', this.__mouseMoveEvent).on('touchmove', this.__mouseMoveEvent);
this.on('mouseover', this.__mouseOverEvent).on('mouseout', this.__mouseOutEvent);
// this.on('click', this.__mouseClickEvent);
// this.__keyboard.addEventListener(EVENT_KEY_RELEASED, this.__keyListenerEvent);
// this.__keyboard.addEventListener(EVENT_KEY_PRESSED, this.__keyListenerEvent);
EventSystem.Instance.addListener("KEY_PRESSED_EVENT", this.__keyListenerEvent);
EventSystem.Instance.addListener("KEY_RELEASED_EVENT", this.__keyListenerEvent);
}
__deactivate() {
this.off('mousedown', this.__mouseClickEvent).off('touchstart', this.__mouseClickEvent);
this.off('mouseupoutside', this.__mouseUpEvent).off('touchendoutside', this.__mouseUpEvent);
this.off('mouseup', this.__mouseUpEvent).off('touchend', this.__mouseUpEvent);
this.off('mousemove', this.__mouseMoveEvent).off('touchmove', this.__mouseMoveEvent);
this.off('mouseover', this.__mouseOverEvent).off('mouseout', this.__mouseOutEvent);
}
__keyListener(evt: KeyboardEvent) {
if (this.selected && evt.key === 'Delete') {
this.__removeFromFloorplan();
}
if (evt.type === "keydown" && evt.key === 'Shift') {
this.__snapToGrid = true;
}
if (evt.type === "keyup" && evt.key === 'Shift') {
this.__snapToGrid = false;
}
}
__vectorToPixels(v) {
return new Vector2(Dimensioning.cmToPixel(v.x), Dimensioning.cmToPixel(v.y));
}
__drawSelectedState() {
}
__drawHoveredOnState() {
}
__drawHoveredOffState() {
}
__click(evt) {
this.selected = true;
this.__isDragging = true;
this.__dragStart(evt);
this.__drawSelectedState();
if (evt !== undefined) {
evt.stopPropagation();
}
}
__mouseOver(evt) {
if (!this.selected) {
this.__drawHoveredOnState();
evt.stopPropagation();
}
}
__mouseOut(evt) {
if (!this.selected) {
this.__drawHoveredOffState();
if (evt !== undefined) {
evt.stopPropagation();
}
}
}
__dragStart(evt) {
this.__isDragging = true;
if (evt) {
evt.stopPropagation();
}
}
__dragEnd(evt) {
this.__isDragging = false;
evt.stopPropagation();
}
__dragMove(evt) {
if (this.__isDragging) {
evt.stopPropagation();
}
}
/**
* The below method is necessary if the remove event was
* triggered from within this view class. For example, this view
* class keeps listening to the delete key pressed. In such a case
* it is the job of this view class to call the "remove()" method of the
* associated method.
*/
__removeFromFloorplan() {
//Stub the sub-classes need to implement this functionality
}
remove() {
this.off('mousedown', this.__mouseDownEvent).off('touchstart', this.__mouseDownEvent);
this.off('mouseupoutside', this.__mouseUpEvent).off('touchendoutside', this.__mouseUpEvent);
this.off('mouseup', this.__mouseUpEvent).off('touchend', this.__mouseUpEvent);
this.off('mousemove', this.__mouseMoveEvent).off('touchmove', this.__mouseMoveEvent);
this.off('mouseover', this.__mouseOverEvent).off('mouseout', this.__mouseOutEvent);
this.off('click', this.__mouseClickEvent);
// this.__keyboard.removeEventListener(EVENT_KEY_RELEASED, this.__keyListenerEvent);
// this.__keyboard.removeEventListener(EVENT_KEY_PRESSED, this.__keyListenerEvent);
EventSystem.Instance.removeListener("KEY_RELEASED_EVENT", this.__keyListenerEvent);
EventSystem.Instance.removeListener("KEY_PRESSED_EVENT", this.__keyListenerEvent);
// this.__keyboard.remove();
if (this.parent) {
this.parent.removeChild(this);
}
}
// addFloorplanListener(type, listener) {
// // this.__eventDispatcher.addEventListener(type, listener);
// EventSystem.Instance.addListener(type, listener);
// }
// removeFloorplanListener(type, listener) {
// // this.__eventDispatcher.removeEventListener(type, listener);
// EventSystem.Instance.removeListener(type, listener);
// }
get selected() {
return this.__isSelected;
}
set selected(flag) {
this.__isSelected = flag;
if (!this.__isSelected) {
this.__drawHoveredOffState();
}
if (flag) {
// this.__eventDispatcher.dispatchEvent({ type: EVENT_2D_SELECTED, item: this });
EventSystem.Instance.sendMessage("SELECTED_2D_EVENT", this);
} else {
// this.__eventDispatcher.dispatchEvent({ type: EVENT_2D_UNSELECTED, item: this });
EventSystem.Instance.sendMessage("UNSELECTED_2D_EVENT", this);
}
}
get interactable() {
return this.__interactable;
}
set interactable(flag) {
this.__interactable = flag;
this.interactive = flag;
this.buttonMode = flag;
}
}

95
src/blueprint/scripts/viewer2d/BoundaryView2D.js

@ -0,0 +1,95 @@
import { Color } from "three";
import {Matrix, Texture} from 'pixi.js';
import { BaseFloorplanViewElement2D } from "./BaseFloorplanViewElement2D";
import { isMobile } from "detect-touch-device";
export class BoundaryView2D extends BaseFloorplanViewElement2D {
constructor(floorplan, options, boundary) {
super(floorplan, options);
this.__options['boundary-point-radius'] = 12.5;
this.__options['boundary-line-thickness'] = 12.5;
this.__options['boundary-point-color'] = '#000000';
this.__options['boundary-line-color'] = '#CC33CC';
for (let opt in options) {
if (this.__options.hasOwnProperty(opt) && options.hasOwnProperty(opt)) {
this.__options[opt] = options[opt];
}
}
this.__options['boundary-point-color'] = new Color(this.__options['boundary-point-color']).getHex();
this.__options['boundary-line-color'] = new Color(this.__options['boundary-line-color']).getHex();
this.__boundary = boundary;
this.pivot.x = this.pivot.y = 0.5;
this.interactive = false;
this.buttonMode = false;
this.__drawHoveredOffState();
}
__drawBoundaryRegion(pointsColor, lineColor){
this.clear();
if(!this.__boundary.points.length){
return;
}
let alpha = 1.0;//0.1;//
let fillAlpha = 1.0;
let radius = this.__options['boundary-point-radius'];
let thickness = this.__options['boundary-line-thickness'];
if (isMobile) {
}
// console.log('BEFORE ::: ', this.fill, this.__boundary.styleType);
this.fill.visible = true;
this.fill.alpha = fillAlpha;
if(this.__boundary.style.colormap){
let matrix = new Matrix();
let scale = Math.min(this.__boundary.width, this.__boundary.height) / this.__boundary.styleRepeat;
matrix = matrix.scale(scale, scale);
let texture = Texture.from(this.__boundary.style.colormap);
this.fill.texture = texture;
this.fill.matrix = matrix;
}
this.fill.color = new Color(this.__boundary.style.color).getHex();
this.lineStyle(thickness, lineColor);
for (let i =0;i <= this.__boundary.points.length;i++){
let index = i % this.__boundary.points.length;
let cmPoint = this.__boundary.points[index];
let pixelPoint = this.__vectorToPixels(cmPoint);
if(i === 0){
this.moveTo(pixelPoint.x, pixelPoint.y);
}
else{
this.lineTo(pixelPoint.x, pixelPoint.y);
}
}
// this.endFill();
this.beginFill(pointsColor, alpha);
for (let i =0;i < this.__boundary.points.length;i++){
let cmPoint = this.__boundary.points[i];
let pixelPoint = this.__vectorToPixels(cmPoint);
this.drawCircle(pixelPoint.x, pixelPoint.y, radius);
}
this.endFill();
}
__drawHoveredOffState() {
super.__drawHoveredOffState();
this.__drawBoundaryRegion(this.__options['boundary-point-color'], this.__options['boundary-line-color']);
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save