From 2a5d0a994522085e74d85d874be4b83bc68be3cd Mon Sep 17 00:00:00 2001 From: Dany Shev Date: Wed, 7 Apr 2021 18:02:44 +0300 Subject: [PATCH 1/3] wip --- .../g.frame.common.camera_controls/.gitignore | 3 + .../g.frame.common.camera_controls/README.md | 20 ++++ .../create-tag.sh | 25 +++++ .../jest.config.js | 10 ++ .../package.json | 57 ++++++++++++ .../src/CameraControls.ts | 72 +++++++++++++++ .../src/CameraControlsAgent.ts | 91 +++++++++++++++++++ .../src/CameraControlsModule.ts | 36 ++++++++ .../src/index.ts | 3 + .../tsconfig.json | 47 ++++++++++ .../tslint.json | 61 +++++++++++++ packages/g.frame.desktop/package.json | 3 +- .../src/controls/OrbitControls.ts | 45 ++++++++- 13 files changed, 471 insertions(+), 2 deletions(-) create mode 100644 packages/g.frame.common.camera_controls/.gitignore create mode 100644 packages/g.frame.common.camera_controls/README.md create mode 100644 packages/g.frame.common.camera_controls/create-tag.sh create mode 100644 packages/g.frame.common.camera_controls/jest.config.js create mode 100644 packages/g.frame.common.camera_controls/package.json create mode 100644 packages/g.frame.common.camera_controls/src/CameraControls.ts create mode 100644 packages/g.frame.common.camera_controls/src/CameraControlsAgent.ts create mode 100644 packages/g.frame.common.camera_controls/src/CameraControlsModule.ts create mode 100644 packages/g.frame.common.camera_controls/src/index.ts create mode 100644 packages/g.frame.common.camera_controls/tsconfig.json create mode 100644 packages/g.frame.common.camera_controls/tslint.json diff --git a/packages/g.frame.common.camera_controls/.gitignore b/packages/g.frame.common.camera_controls/.gitignore new file mode 100644 index 0000000..5b64f7f --- /dev/null +++ b/packages/g.frame.common.camera_controls/.gitignore @@ -0,0 +1,3 @@ +node_modules +.idea +.DS_Store \ No newline at end of file diff --git a/packages/g.frame.common.camera_controls/README.md b/packages/g.frame.common.camera_controls/README.md new file mode 100644 index 0000000..620cc5b --- /dev/null +++ b/packages/g.frame.common.camera_controls/README.md @@ -0,0 +1,20 @@ +# g.frame.components.window +Module repo template for g.frame + +## How to use +* Create new repo and use this project as template +* Clone it +* Change all `g.frame.components.window` occurrences to your module name `g.frame.module_name` +* Rename `.github_` folder to `.github` +* Update to use latest version of `g.frame` and `three` +* Use `npm install` to install all dependencies + + +## How to build +* Use `npm run build` to build your module +* Use `npm run lint` to lint your code +* Use `npm run test` to run unit tests +* Use `npm run docs` to generate docs + +## Useful links +* `g.frame` repo https://github.com/VeryBigThings/g.frame \ No newline at end of file diff --git a/packages/g.frame.common.camera_controls/create-tag.sh b/packages/g.frame.common.camera_controls/create-tag.sh new file mode 100644 index 0000000..b1fd613 --- /dev/null +++ b/packages/g.frame.common.camera_controls/create-tag.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# get current commit hash for tag +commit=$(git rev-parse HEAD) + +# get repo name from git +remote=$(git config --get remote.origin.url) +repo=$(basename $remote .git) + +# get version from package.json file +VERSION=$(jq -r '.version' package.json) +# create new tag +new=v$VERSION +# show new tag +echo $new + +# POST a new ref to repo via Github API +curl -s -X POST https://api.github.com/repos/$REPO_OWNER/$repo/git/refs \ +-H "Authorization: token $GITHUB_TOKEN" \ +-d @- << EOF +{ + "ref": "refs/tags/$new", + "sha": "$commit" +} +EOF \ No newline at end of file diff --git a/packages/g.frame.common.camera_controls/jest.config.js b/packages/g.frame.common.camera_controls/jest.config.js new file mode 100644 index 0000000..cdd0a3f --- /dev/null +++ b/packages/g.frame.common.camera_controls/jest.config.js @@ -0,0 +1,10 @@ +const base = require("../../jest.config.base.js"); +const pack = require("./package"); + +module.exports = { + ...base, + displayName: pack.name, + name: pack.name, + rootDir: "../..", + testMatch: [`/packages/${pack.name}/tests/**/.*.(test|spec)).(js|ts)`], +}; \ No newline at end of file diff --git a/packages/g.frame.common.camera_controls/package.json b/packages/g.frame.common.camera_controls/package.json new file mode 100644 index 0000000..072b664 --- /dev/null +++ b/packages/g.frame.common.camera_controls/package.json @@ -0,0 +1,57 @@ +{ + "name": "@verybigthings/g.frame.common.camera_controls", + "version": "0.1.0", + "description": "Template module from g.frame", + "main": "build/main/index.js", + "typings": "build/main/index.d.ts", + "directories": { + "doc": "docs" + }, + "scripts": { + "build": "run-s clean && run-p build:*", + "build:main": "tsc -p tsconfig.json", + "clean": "trash build test", + "test": "jest --passWithNoTests", + "lint": "tslint 'src/**/*.ts?(x)'", + "docs": "trash docs && typedoc && touch docs/.nojekyll" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/VeryBigThings/g.frame.git" + }, + "keywords": [ + "webgl", + "three.js", + "g.frame" + ], + "author": "Very Big Things", + "license": "ISC", + "bugs": { + "url": "https://github.com/VeryBigThings/g.frame/issues" + }, + "publishConfig": { + "registry": "https://npm.pkg.github.com/@VeryBigThings" + }, + "homepage": "https://github.com/VeryBigThings/g.frame#readme", + "dependencies": { + }, + "peerDependencies": { + "@verybigthings/g.frame.core": "0.1.6", + "three": "^0.123.0" + }, + "devDependencies": { + "@types/jest": "^25.1.4", + "@types/node": "^13.9.1", + "copyfiles": "^2.2.0", + "jest": "^25.1.0", + "npm-run-all": "^4.1.5", + "trash-cli": "^3.0.0", + "ts-jest": "^25.2.1", + "tslint": "^6.1.0", + "typedoc": "^0.17.4", + "typescript": "^3.8.3", + "@verybigthings/g.frame.core": "0.1.6", + "three": "^0.123.0" + }, + "gitHead": "2adcda2e0de0598d1351dea6068d39f70edc7f99" +} diff --git a/packages/g.frame.common.camera_controls/src/CameraControls.ts b/packages/g.frame.common.camera_controls/src/CameraControls.ts new file mode 100644 index 0000000..27f97e2 --- /dev/null +++ b/packages/g.frame.common.camera_controls/src/CameraControls.ts @@ -0,0 +1,72 @@ +import {EventDispatcher, Quaternion, Vector3} from 'three'; +import {Constructor} from '@verybigthings/g.frame.core'; + +export class CameraControls extends EventDispatcher { + public __agentConstructor: Function; + public enabled: boolean = false; + public readonly platform: string; + + constructor() { + super(); + } + + setPosition(newX: number, newY: number, newZ: number) { + + } + + copyPosition(newPosition: Vector3) { + this.setPosition(newPosition.x, newPosition.y, newPosition.z); + } + + addPosition(addedPosition: Vector3) { + + } + + getPosition(): Vector3 { + return new Vector3(); + } + + setOrientation(newOrientation: Quaternion) { + + } + + getOrientation(): Quaternion { + return new Quaternion(); + } + + setPitch(newPitch: number): void { + + } + + setYaw(newYaw: number): void { + + } + + setRoll(newRoll: number): void { + + } + + getPitch(): number { + return 0; + } + + getYaw(): number { + return 0; + } + + getRoll(): number { + return 0; + } + + + getSpecific(constructorFunction: Constructor): T { + return new constructorFunction(); + } + + + setPositions(positionsMap: { + [platformName: string]: Vector3 | Array | number | { x: number; y: number; z: number } + }): void { + + } +} diff --git a/packages/g.frame.common.camera_controls/src/CameraControlsAgent.ts b/packages/g.frame.common.camera_controls/src/CameraControlsAgent.ts new file mode 100644 index 0000000..ab65fd8 --- /dev/null +++ b/packages/g.frame.common.camera_controls/src/CameraControlsAgent.ts @@ -0,0 +1,91 @@ +import {Quaternion, Vector3} from 'three'; +import {CameraControls} from './CameraControls'; +import {Constructor} from '@verybigthings/g.frame.core'; + +export class CameraControlsAgent extends CameraControls { + + constructor(private instances: Array) { + super(); + } + + getSpecific(constructorFunction: Constructor): T { + for (let i = 0; i < this.instances.length; i++) { + if (Object.getPrototypeOf(this.instances[i]).constructor === constructorFunction) return this.instances[i]; + } + } + + setOrientation(newOrientation: Quaternion) { + for (let i = 0; i < this.instances.length; i++) { + this.instances[i].setOrientation(newOrientation); + } + } + + getOrientation(): Quaternion { + for (let i = 0; i < this.instances.length; i++) { + const quaternion = this.instances[i].getOrientation(); + if (quaternion) return quaternion; + } + } + + setPositions(positionsMap: { + [platformName: string]: Vector3 | Array | number | { x: number; y: number; z: number } + }): void { + for (let i = 0; i < this.instances.length; i++) { + const platform = this.instances[i].platform; + if (positionsMap.hasOwnProperty(platform)) { + let position: Vector3; + if (positionsMap[platform] instanceof Array) { + position = new Vector3(positionsMap[platform][0], positionsMap[platform][1], positionsMap[platform][2]); + } else if (typeof positionsMap[platform] === 'number') { + position = new Vector3(positionsMap[platform], positionsMap[platform], positionsMap[platform]); + } else if (positionsMap[platform] instanceof Vector3) { + position = new Vector3().copy(positionsMap[platform]); + } + + this.instances[i].copyPosition(position); + } + } + } + + setPitch(pitch: number) { + for (let i = 0; i < this.instances.length; i++) { + this.instances[i].setPitch(pitch); + } + } + + setYaw(yaw: number) { + for (let i = 0; i < this.instances.length; i++) { + this.instances[i].setYaw(yaw); + } + } + + setRoll(roll: number) { + for (let i = 0; i < this.instances.length; i++) { + this.instances[i].setRoll(roll); + } + } + + getPitch(): number { + for (let i = 0; i < this.instances.length; i++) { + const pitch = this.instances[i].getPitch(); + if (!isNaN(pitch)) return pitch; + } + } + + getYaw(): number { + for (let i = 0; i < this.instances.length; i++) { + const yaw = this.instances[i].getYaw(); + if (yaw) return yaw; + } + } + + getRoll(): number { + for (let i = 0; i < this.instances.length; i++) { + const roll = this.instances[i].getRoll(); + if (!isNaN(roll)) return roll; + } + } + +} + +CameraControls.prototype.__agentConstructor = CameraControlsAgent; \ No newline at end of file diff --git a/packages/g.frame.common.camera_controls/src/CameraControlsModule.ts b/packages/g.frame.common.camera_controls/src/CameraControlsModule.ts new file mode 100644 index 0000000..2135871 --- /dev/null +++ b/packages/g.frame.common.camera_controls/src/CameraControlsModule.ts @@ -0,0 +1,36 @@ +import {AbstractModule, AbstractModuleStatus, ConstructorInstanceMap} from '@verybigthings/g.frame.core'; + + +export class CameraControlsModule extends AbstractModule { + + constructor() { + super(); + } + + async preInit(): Promise { + console.warn('CameraControlsModule pre-initialization prevented. ' + + 'You need to extend this module, look `g.frame.desktop` module.'); + return { + enabled: false + }; + } + + async onInit(data: any): Promise> { + return []; + } + + afterInit(agents: ConstructorInstanceMap): void { + } + + onUpdate(params: { currentTime: number; frame: any }): void { + } + + onDestroy(): void { + } + + onResume(): void { + } + + onPause(): void { + } +} \ No newline at end of file diff --git a/packages/g.frame.common.camera_controls/src/index.ts b/packages/g.frame.common.camera_controls/src/index.ts new file mode 100644 index 0000000..a76f56f --- /dev/null +++ b/packages/g.frame.common.camera_controls/src/index.ts @@ -0,0 +1,3 @@ +export * from './CameraControls'; +export * from './CameraControlsAgent'; +export * from './CameraWrapperControls'; \ No newline at end of file diff --git a/packages/g.frame.common.camera_controls/tsconfig.json b/packages/g.frame.common.camera_controls/tsconfig.json new file mode 100644 index 0000000..10f9201 --- /dev/null +++ b/packages/g.frame.common.camera_controls/tsconfig.json @@ -0,0 +1,47 @@ +{ + "compilerOptions": { + "target": "es2017", + "outDir": "build/main", + "rootDir": "src", + "moduleResolution": "node", + "module": "commonjs", + "declaration": true, + "inlineSourceMap": true, + "resolveJsonModule": true, + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, + // "strict": true /* Enable all strict type-checking options. */, + + /* Strict Type-Checking Options */ + // "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, + // "strictNullChecks": true /* Enable strict null checks. */, + // "strictFunctionTypes": true /* Enable strict checking of function types. */, + // "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, + // "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, + // "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, + + // /* Additional Checks */ + // "noUnusedLocals": true /* Report errors on unused locals. */, + // "noUnusedParameters": true /* Report errors on unused parameters. */, + // "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, + // "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, + + /* Debugging Options */ + "traceResolution": false /* Report module resolution log messages. */, + "listEmittedFiles": false /* Print names of generated files part of the compilation. */, + "listFiles": false /* Print names of files part of the compilation. */, + "pretty": true /* Stylize errors and messages using color and context. */, + + // /* Experimental Options */ + "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, +// "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, + + "lib": ["es2017", "dom"], + "types": ["node", "jest"], + "typeRoots": ["node_modules/@types", "src/types"] + }, + "include": [ + "src/**/*" + ], + "exclude": ["node_modules/**", "src/**/*.spec.ts"], + "compileOnSave": false +} \ No newline at end of file diff --git a/packages/g.frame.common.camera_controls/tslint.json b/packages/g.frame.common.camera_controls/tslint.json new file mode 100644 index 0000000..b527ca6 --- /dev/null +++ b/packages/g.frame.common.camera_controls/tslint.json @@ -0,0 +1,61 @@ +{ + "rules": { + "class-name": true, + "comment-format": [ + true, + "check-space" + ], + "indent": [ + true, + "spaces" + ], + "no-duplicate-variable": true, + "no-eval": true, + "no-internal-module": true, + "no-trailing-whitespace": true, + "no-unsafe-finally": true, + "no-var-keyword": true, + "one-line": [ + true, + "check-open-brace", + "check-whitespace" + ], + "quotemark": [ + true, + "single" + ], + "semicolon": [ + true, + "always" + ], + "triple-equals": [ + true, + "allow-null-check" + ], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + } + ], + "variable-name": [ + true, + "ban-keywords" + ], + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ], + "space-within-parens": [ + true + ] + } +} \ No newline at end of file diff --git a/packages/g.frame.desktop/package.json b/packages/g.frame.desktop/package.json index 8469c23..98041d3 100644 --- a/packages/g.frame.desktop/package.json +++ b/packages/g.frame.desktop/package.json @@ -54,7 +54,8 @@ "typedoc": "^0.17.4", "typescript": "^3.8.3", "three": "^0.123.0", - "@verybigthings/g.frame.core": "^0.1.6" + "@verybigthings/g.frame.core": "^0.1.6", + "@verybigthings/g.frame.common.camera_controls": "^0.1.0" }, "gitHead": "2adcda2e0de0598d1351dea6068d39f70edc7f99" } diff --git a/packages/g.frame.desktop/src/controls/OrbitControls.ts b/packages/g.frame.desktop/src/controls/OrbitControls.ts index b9fd963..5292347 100644 --- a/packages/g.frame.desktop/src/controls/OrbitControls.ts +++ b/packages/g.frame.desktop/src/controls/OrbitControls.ts @@ -9,6 +9,7 @@ import { Vector2, Vector3 } from 'three'; +import {CameraControls} from '@verybigthings/g.frame.common.camera_controls'; const STATE = { NONE: -1, @@ -39,7 +40,7 @@ const EPS = 0.000001; * Zoom - middle mouse, or mousewheel / touch: two finger spread or squish * Pan - right mouse, or arrow keys / touch: three finger swipe */ -export class OrbitControls extends EventDispatcher { +export class OrbitControls extends CameraControls { object: Object3D; object0: Object3D; domElement: HTMLElement | HTMLDocument; @@ -490,6 +491,48 @@ export class OrbitControls extends EventDispatcher { this.enableZoom = !value; } + getOrientation(): Quaternion { + const direction = new Vector3().copy(this.object.localToWorld(this.object.position.clone())).sub(this.object.localToWorld(this.target.clone())); + const quaternion = new Quaternion().setFromUnitVectors(direction, new Vector3(0, 0, -1)); + return quaternion; + } + + setOrientation(newOrientation: Quaternion) { + newOrientation.normalize(); + const vector = new Vector3().applyQuaternion(newOrientation); + this.target.copy(this.object.localToWorld(this.object.position.clone())).add(vector); + this.update(); + } + + setPosition(newX: number, newY: number, newZ: number) { + if (this.enabled === false) return; + // console.log(this, 'orbit controls') + const targetToObjectVector = this.target.clone().sub(this.object.position.clone()); + // console.log(this.target, 'old target pos', this.target.distanceTo(this.object.position), 'old distance') + const newTargetPosition = new Vector3(typeof newX === 'number' ? newX : this.object.position.x, + typeof newY === 'number' ? newY : this.object.position.y, + typeof newZ === 'number' ? newZ : this.object.position.z + ).add(targetToObjectVector); + + this.target.copy(newTargetPosition); + this.object.position.copy(newTargetPosition.sub(targetToObjectVector)); + // console.log(this.target, 'new target pos', this.target.distanceTo(this.object.position), 'new distance') + this.update(); + } + + getPosition() { + return this.object.position.clone(); + } + + addPosition(addedPosition: Vector3) { + if (this.enabled === false) return; + const targetToObjectVector = this.target.clone().sub(this.object.position.clone()); + const newPos = this.object.position.clone().add(addedPosition); + this.object.position.copy(newPos); + this.target.copy(this.object.position.clone().add(targetToObjectVector)); + this.update(); + } + update() { const position = this.object.position; this.updateOffset.copy(position).sub(this.target); From 3cc6f72398319db339da0bc9f13839b679d9e9f2 Mon Sep 17 00:00:00 2001 From: Dany Shev Date: Wed, 7 Apr 2021 18:52:48 +0300 Subject: [PATCH 2/3] build fix --- packages/g.frame.common.camera_controls/src/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/g.frame.common.camera_controls/src/index.ts b/packages/g.frame.common.camera_controls/src/index.ts index a76f56f..39ed6a0 100644 --- a/packages/g.frame.common.camera_controls/src/index.ts +++ b/packages/g.frame.common.camera_controls/src/index.ts @@ -1,3 +1,2 @@ export * from './CameraControls'; -export * from './CameraControlsAgent'; -export * from './CameraWrapperControls'; \ No newline at end of file +export * from './CameraControlsAgent'; \ No newline at end of file From a20ee98bf96bb9442d46bb399d55479127968a4a Mon Sep 17 00:00:00 2001 From: Dany Shev Date: Wed, 7 Apr 2021 20:07:44 +0300 Subject: [PATCH 3/3] setPositions fixed --- .../g.frame.common.camera_controls/src/CameraControlsAgent.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/g.frame.common.camera_controls/src/CameraControlsAgent.ts b/packages/g.frame.common.camera_controls/src/CameraControlsAgent.ts index ab65fd8..0b88b0e 100644 --- a/packages/g.frame.common.camera_controls/src/CameraControlsAgent.ts +++ b/packages/g.frame.common.camera_controls/src/CameraControlsAgent.ts @@ -40,6 +40,9 @@ export class CameraControlsAgent extends CameraControls { position = new Vector3(positionsMap[platform], positionsMap[platform], positionsMap[platform]); } else if (positionsMap[platform] instanceof Vector3) { position = new Vector3().copy(positionsMap[platform]); + } else if (positionsMap[platform] instanceof Object) { + // @ts-ignore + position = new Vector3(positionsMap[platform].x, positionsMap[platform].y, positionsMap[platform].z); } this.instances[i].copyPosition(position);