Stupid hack due to race condition with click menu.

This commit is contained in:
Michael Mainguy 2024-06-05 16:01:49 -05:00
parent 7315e3397a
commit f07ea11817
14 changed files with 368 additions and 72 deletions

View File

@ -46,13 +46,13 @@
<img id="loadingGrid" src="/assets/grid6.jpg"/>
<script>
if (typeof navigator.serviceWorker !== 'undefined') {
if (localStorage.getItem('serviceWorkerVersion') != '8') {
if (localStorage.getItem('serviceWorkerVersion') < '9') {
caches.keys().then(cacheNames => {
cacheNames.forEach(cacheName => {
caches.delete(cacheName);
});
});
localStorage.setItem('serviceWorkerVersion', '8');
localStorage.setItem('serviceWorkerVersion', '9');
}
navigator.serviceWorker.register('/sw.js', {updateViaCache: 'none'});
}

79
package-lock.json generated
View File

@ -8,14 +8,14 @@
"name": "immersive",
"version": "0.0.7",
"dependencies": {
"@babylonjs/core": "^7.6.0",
"@babylonjs/gui": "^7.6.0",
"@babylonjs/core": "^7.9.0",
"@babylonjs/gui": "^7.9.0",
"@babylonjs/havok": "1.3.4",
"@babylonjs/inspector": "^7.6.0",
"@babylonjs/loaders": "^7.6.0",
"@babylonjs/materials": "^7.6.0",
"@babylonjs/procedural-textures": "^7.6.0",
"@babylonjs/serializers": "^7.6.0",
"@babylonjs/inspector": "^7.9.0",
"@babylonjs/loaders": "^7.9.0",
"@babylonjs/materials": "^7.9.0",
"@babylonjs/procedural-textures": "^7.9.0",
"@babylonjs/serializers": "^7.9.0",
"@maptiler/client": "1.8.1",
"@picovoice/cobra-web": "^2.0.3",
"@picovoice/eagle-web": "^1.0.0",
@ -27,7 +27,7 @@
"@types/react": "^18.2.72",
"@types/react-dom": "^18.2.22",
"axios": "^1.6.8",
"babylon-html": "^0.0.3",
"babylon-html": "0.0.3",
"dom-to-image-more": "^3.3.0",
"earcut": "^2.2.4",
"events": "^3.3.0",
@ -35,6 +35,7 @@
"hls.js": "^1.1.4",
"loglevel": "^1.9.1",
"niceware": "^4.0.0",
"peer-lite": "2.0.2",
"pouchdb": "^8.0.1",
"pouchdb-find": "^8.0.1",
"query-string": "^8.1.0",
@ -55,15 +56,30 @@
"node": ">=18.0.0"
}
},
"../babylon-html": {
"version": "0.0.3",
"extraneous": true,
"license": "MIT",
"dependencies": {
"@babylonjs/core": "^7.1.0",
"dom-to-image-more": "^3.3.0"
},
"devDependencies": {
"@types/dom-to-image": "^2.6.7",
"ts-node": "^10.9.2",
"tsup": "^8.0.2",
"typescript": "^5.4.5"
}
},
"node_modules/@babylonjs/core": {
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/@babylonjs/core/-/core-7.6.0.tgz",
"integrity": "sha512-Pr5TlHQBdTYLkw+HmWZo1V6VYnP48wxEGBAscHcgZuuETo2ITCmsRLv0o+XY0QL1eAL8grQBM5eOkAInNt4SvA=="
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/@babylonjs/core/-/core-7.9.0.tgz",
"integrity": "sha512-ZhXlcnEZSpu8c4jH3bqwfUF8RZdPZTltkYRxZTwFlqkTy6qI80mCMwQr/s3aKGSmGAQKvi37LAnGV7264W+/XQ=="
},
"node_modules/@babylonjs/gui": {
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/@babylonjs/gui/-/gui-7.6.0.tgz",
"integrity": "sha512-5r954RVrnEvSCw/WKwl6CdKb5PIVEMyF6WKS+bDku3PrwaoTUqkd1jlhmyaH6k2bL/bcoaz25ts04TK6YrbmXA==",
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/@babylonjs/gui/-/gui-7.9.0.tgz",
"integrity": "sha512-61jsrv5h+GpSwQZfiR6/qzXHOuROR3/EWYf8aNBzItvxHAiSeNxpUNR5FdXu2sxBDCMEyUc9fZtO+9wlH0PDYw==",
"peerDependencies": {
"@babylonjs/core": "^7.0.0"
}
@ -89,9 +105,9 @@
}
},
"node_modules/@babylonjs/inspector": {
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/@babylonjs/inspector/-/inspector-7.6.0.tgz",
"integrity": "sha512-utytbidkVhYXNhVY5XOuGIHCPdmHrHw9q1rr9+P7nwUUwTtl3duAQiU8TE/w/6MUejg97kyN6lBGRqXAWpL5nA==",
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/@babylonjs/inspector/-/inspector-7.9.0.tgz",
"integrity": "sha512-bkFAiBBwDbnAmwJkYjlvX8/5CpCKqbkQd/2vcePMDFBh676YwadtwDsJFPfDLL8GRjKyRb4dm7O07rS2MvVQ3g==",
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^6.1.0",
"@fortawesome/free-regular-svg-icons": "^6.0.0",
@ -109,34 +125,34 @@
}
},
"node_modules/@babylonjs/loaders": {
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/@babylonjs/loaders/-/loaders-7.6.0.tgz",
"integrity": "sha512-7tt/ImGExADJx5wGs/3vz8tijg1FHuVT2c/8dp0Q+qv3v47KJIgCOtggoXCVDTo+xYj2fQWtucmXwkNhIizg7w==",
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/@babylonjs/loaders/-/loaders-7.9.0.tgz",
"integrity": "sha512-/wmLNkHhJkTZ4+0TM2aWc76sTgndIZyVNQ8jxQHeCwfq8M3X4DbBQyHC3JZJx+dplz6b0eD6m2oiSEmbBvZwQw==",
"peerDependencies": {
"@babylonjs/core": "^7.0.0",
"babylonjs-gltf2interface": "^7.0.0"
}
},
"node_modules/@babylonjs/materials": {
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/@babylonjs/materials/-/materials-7.6.0.tgz",
"integrity": "sha512-o5PcKNf/NE+P81E1fQyuoNrCND6dV5RJZga03JzHIs48/+2veq11Dj4FGAOinmqQwe/0U2yrl3v4hsRVwt4YtQ==",
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/@babylonjs/materials/-/materials-7.9.0.tgz",
"integrity": "sha512-M9s6d5+9sNOJAQHMHKj880dQRUAZoxoHw4VlSeGhETFKFKk9iHGRCOmhmwbU68R1wdIHPUbDV4gijv/pNlcCqQ==",
"peerDependencies": {
"@babylonjs/core": "^7.0.0"
}
},
"node_modules/@babylonjs/procedural-textures": {
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/@babylonjs/procedural-textures/-/procedural-textures-7.6.0.tgz",
"integrity": "sha512-37Dheb8kGX0lWRevFw3mqMtuoJrJ+TT2bEQB/9BOmAKS2yEb2xlLlswkn7UaB4oHax8XzaY9N63zTSzzWj978Q==",
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/@babylonjs/procedural-textures/-/procedural-textures-7.9.0.tgz",
"integrity": "sha512-rNXvaS/wgpvfw93VTmkxFa/gzZowh3Xi5Lc8KjCKJFHth/V7fv+YChYGxRoNTVFDkOiyDRJPBKkJaepoTtsKlw==",
"peerDependencies": {
"@babylonjs/core": "^7.0.0"
}
},
"node_modules/@babylonjs/serializers": {
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/@babylonjs/serializers/-/serializers-7.6.0.tgz",
"integrity": "sha512-U/umdH2dAcEuyb1OcaemV2LOgIohsoWAgUriub0SxA+DLlpiyEt6HUSvM+aX/90UyGNz5Dpb4VZXbqBIrUa0Hg==",
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/@babylonjs/serializers/-/serializers-7.9.0.tgz",
"integrity": "sha512-y1wnxGDneECHqW/L2cYsJ6e0aIifDk9eb02H/ORvhDnCrEwEL3cabh+Ouvsrcw/giPQPsZ6XB36OAoZDV5i1Rw==",
"peerDependencies": {
"@babylonjs/core": "^7.0.0",
"babylonjs-gltf2interface": "^7.0.0"
@ -2298,6 +2314,11 @@
"node": "*"
}
},
"node_modules/peer-lite": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/peer-lite/-/peer-lite-2.0.2.tgz",
"integrity": "sha512-/60abreInKdWz7XMDZbjqp5X9QCiwgI/Sf9rdXCyvu7Rgq4Xd3E/Kwrf8GnSybUIhE0QcYybrYwEZxFn6NYjIQ=="
},
"node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",

View File

@ -16,18 +16,18 @@
"havok": "cp ./node_modules/@babylonjs/havok/lib/esm/HavokPhysics.wasm ./node_modules/.vite/deps"
},
"dependencies": {
"@babylonjs/core": "^7.6.0",
"@babylonjs/gui": "^7.6.0",
"@babylonjs/core": "^7.9.0",
"@babylonjs/gui": "^7.9.0",
"@babylonjs/havok": "1.3.4",
"@babylonjs/inspector": "^7.6.0",
"@babylonjs/loaders": "^7.6.0",
"@babylonjs/materials": "^7.6.0",
"@babylonjs/procedural-textures": "^7.6.0",
"@babylonjs/serializers": "^7.6.0",
"@babylonjs/inspector": "^7.9.0",
"@babylonjs/loaders": "^7.9.0",
"@babylonjs/materials": "^7.9.0",
"@babylonjs/procedural-textures": "^7.9.0",
"@babylonjs/serializers": "^7.9.0",
"@maptiler/client": "1.8.1",
"@picovoice/cobra-web": "^2.0.3",
"@picovoice/eagle-web": "^1.0.0",
"@picovoice/web-voice-processor": "^4.0.9",
"@maptiler/client": "1.8.1",
"@typed-mxgraph/typed-mxgraph": "^1.0.8",
"@types/dom-to-image": "^2.6.7",
"@types/file-saver": "^2.0.6",
@ -35,7 +35,7 @@
"@types/react": "^18.2.72",
"@types/react-dom": "^18.2.22",
"axios": "^1.6.8",
"babylon-html": "^0.0.3",
"babylon-html": "0.0.3",
"dom-to-image-more": "^3.3.0",
"earcut": "^2.2.4",
"events": "^3.3.0",
@ -43,6 +43,7 @@
"hls.js": "^1.1.4",
"loglevel": "^1.9.1",
"niceware": "^4.0.0",
"peer-lite": "2.0.2",
"pouchdb": "^8.0.1",
"pouchdb-find": "^8.0.1",
"query-string": "^8.1.0",

View File

@ -38,7 +38,8 @@ export class DiagramMenuManager {
});
this.toolbox = new Toolbox();
this.scaleMenu = new ScaleMenu2(this._notifier);
const clickMenu = this.createClickMenu(this.toolbox.handleMesh, null);
clickMenu.dispose();
controllers.controllerObservable.add((event: ControllerEvent) => {
if (event.type == ControllerEventType.B_BUTTON) {
if (event.value > .8) {
@ -53,6 +54,7 @@ export class DiagramMenuManager {
if (toolY > (cameraPos.y - .2)) {
this.toolbox.handleMesh.position.y = localCamera.y - .2;
}
const inputY = this._inputTextView.handleMesh.absolutePosition.y;
if (inputY > (cameraPos.y - .2)) {
this._inputTextView.handleMesh.position.y = localCamera.y - .2;

View File

@ -15,6 +15,7 @@ import {v4 as uuidv4} from 'uuid';
import {createLabel} from "./functions/createLabel";
import {DiagramEventObserverMask} from "./types/diagramEventObserverMask";
import log, {Logger} from "loglevel";
import {xyztovec} from "./functions/vectorConversion";
type DiagramObjectOptionsType = {
diagramEntity?: DiagramEntity,
@ -204,7 +205,3 @@ export class DiagramObject {
this._mesh.rotation.x = Math.PI / 2;
}
}
function xyztovec(xyz: { x, y, z }): Vector3 {
return new Vector3(xyz.x, xyz.y, xyz.z);
}

View File

@ -3,3 +3,7 @@ import {Vector3} from "@babylonjs/core";
export function vectoxys(v: Vector3): { x, y, z } {
return {x: v.x, y: v.y, z: v.z};
}
export function xyztovec(xyz: { x, y, z }): Vector3 {
return new Vector3(xyz.x, xyz.y, xyz.z);
}

View File

@ -1,13 +1,17 @@
import log from "loglevel";
import {DiagramEntity} from "../../diagram/types/diagramEntity";
import {Observable} from "@babylonjs/core";
import {UserModelType} from "../../users/userTypes";
export function syncDoc(info: any, onDBRemoveObservable: Observable<DiagramEntity>, onDBUpdateObservable: Observable<DiagramEntity>) {
export function syncDoc(info: any, onDBRemoveObservable: Observable<DiagramEntity>, onDBUpdateObservable: Observable<DiagramEntity>, onUserObservable: Observable<UserModelType>) {
const logger = log.getLogger('syncDoc');
logger.debug(info);
if (info.direction == 'pull') {
const docs = info.change.docs;
for (const doc of docs) {
if (doc.type == 'user') {
//onUserObservable.notifyObservers(doc, -1);
} else {
logger.debug(doc);
if (doc._deleted) {
logger.debug('Delete', doc);
@ -15,8 +19,7 @@ export function syncDoc(info: any, onDBRemoveObservable: Observable<DiagramEntit
} else {
onDBUpdateObservable.notifyObservers(doc, 1);
}
}
}
}
}

View File

@ -9,12 +9,14 @@ import {getPath} from "../util/functions/getPath";
import {DiagramEventObserverMask} from "../diagram/types/diagramEventObserverMask";
import {syncDoc} from "./functions/syncDoc";
import {checkDb} from "./functions/checkDb";
import {UserModelType} from "../users/userTypes";
import {getMe} from "../util/me";
export class PouchdbPersistenceManager {
private _logger: Logger = log.getLogger('PouchdbPersistenceManager');
onDBUpdateObservable: Observable<DiagramEntity> = new Observable<DiagramEntity>();
onDBRemoveObservable: Observable<DiagramEntity> = new Observable<DiagramEntity>();
onDBEntityUpdateObservable: Observable<DiagramEntity> = new Observable<DiagramEntity>();
onDBEntityRemoveObservable: Observable<DiagramEntity> = new Observable<DiagramEntity>();
onUserObservable: Observable<UserModelType> = new Observable<UserModelType>();
private db: PouchDB;
private remote: PouchDB;
private user: string;
@ -40,9 +42,9 @@ export class PouchdbPersistenceManager {
}
}, DiagramEventObserverMask.TO_DB);
this.onDBUpdateObservable.add((evt) => {
this.onDBEntityUpdateObservable.add((evt) => {
this._logger.debug(evt);
if (evt.id != 'metadata') {
if (evt.id != 'metadata' && evt.type != 'user') {
diagramManager.onDiagramEventObservable.notifyObservers({
type: DiagramEventType.ADD,
entity: evt
@ -52,14 +54,37 @@ export class PouchdbPersistenceManager {
}
});
this.onUserObservable.add((evt) => {
if (evt.id == getMe()) {
this.updateUser(evt);
}
});
this.onDBRemoveObservable.add((entity) => {
this.onDBEntityRemoveObservable.add((entity) => {
this._logger.debug(entity);
diagramManager.onDiagramEventObservable.notifyObservers(
{type: DiagramEventType.REMOVE, entity: entity}, DiagramEventObserverMask.FROM_DB);
});
}
private async updateUser(user: UserModelType) {
try {
const doc = await this.db.get(user.id);
if (doc) {
const newDoc = {...doc, ...user};
await this.db.put(newDoc);
}
} catch (err) {
if (err.status == 404) {
await this.db.put({...user, _id: user.id});
} else {
this._logger.error(err);
}
}
}
public async remove(id: string) {
if (!id) {
return;
@ -118,7 +143,7 @@ export class PouchdbPersistenceManager {
const friendly = localStorage.getItem(current);
if (friendly) {
this._logger.debug('local friendly name found ', friendly, ' setting metadata');
const newDoc = {_id: 'metadata', friendly: friendly};
const newDoc = {_id: 'metadata', id: 'metadata', friendly: friendly};
await this.db.put(newDoc);
} else {
this._logger.debug('no friendly name found');
@ -138,7 +163,7 @@ export class PouchdbPersistenceManager {
current = 'localdb';
}
this.db = new PouchDB(current, {auto_compaction: true});
await this.db.compact();
//await this.db.compact();
if (sync) {
await this.setupMetadata(current);
await this.beginSync(current);
@ -161,9 +186,14 @@ export class PouchdbPersistenceManager {
if (clear) {
this.remove(entity.id);
} else {
this.onDBUpdateObservable.notifyObservers(entity.doc, DiagramEventObserverMask.FROM_DB);
if (entity.type == 'user') {
this.onUserObservable.notifyObservers(entity.doc);
} else {
if (entity.id != 'metadata') {
this.onDBEntityUpdateObservable.notifyObservers(entity.doc, DiagramEventObserverMask.FROM_DB);
}
}
}
}
if (clear) {
localStorage.removeItem('clearLocal');
@ -214,7 +244,7 @@ export class PouchdbPersistenceManager {
this._logger.debug(dbInfo);
this.db.sync(this.remote, {live: true, retry: true})
.on('change', (info) => {
syncDoc(info, this.onDBRemoveObservable, this.onDBUpdateObservable);
syncDoc(info, this.onDBEntityRemoveObservable, this.onDBEntityUpdateObservable, this.onUserObservable);
})
.on('active', (info) => {
this._logger.debug('sync active', info)

View File

@ -88,7 +88,7 @@ export class MaptilerMap {
const result = await mapTilerClient.geocoding.forward(name)
if (result.features.length > 0) {
this.setInitialData(result.features[0].center[1], result.features[0].center[0], zoom);
const tileXY = await this.getTileXY(this._lat, this._lon);
const tileXY = this.getTileXY(this._lat, this._lon);
const output = this.getTile(tileXY[0], tileXY[1], zoom);
this.onReadyObservable.notifyObservers({
lat: this._lat,

View File

@ -2,7 +2,7 @@ import {AbstractMesh, GizmoManager, IAxisScaleGizmo, Observable} from "@babylonj
import {DefaultScene} from "../defaultScene";
import {DiagramEvent, DiagramEventType} from "../diagram/types/diagramEntity";
import {toDiagramEntity} from "../diagram/functions/toDiagramEntity";
import {displayDebug} from "../util/displayDebug";
export class ScaleMenu2 {
private readonly _gizmoManager: GizmoManager;
@ -29,7 +29,7 @@ export class ScaleMenu2 {
if (this.mesh.scaling.z < .01) {
this.mesh.scaling.z = .01;
}
displayDebug([this.mesh.scaling.x.toString(), this.mesh.scaling.y.toString(), this.mesh.scaling.z.toString()])
const entity = toDiagramEntity(this.mesh);
this._notifier.notifyObservers({type: DiagramEventType.MODIFY, entity: entity});
});

View File

@ -1,4 +1,4 @@
import {AbstractMesh, ActionEvent, Observable, Scene, TransformNode} from "@babylonjs/core";
import {AbstractMesh, ActionEvent, Observable, Scene, TransformNode, Vector3} from "@babylonjs/core";
import {HtmlButton} from "babylon-html";
const POINTER_UP = "pointerup";
@ -56,11 +56,14 @@ export class ClickMenu {
const platform = scene.getMeshByName("platform");
this._transformNode.parent = scene.activeCamera;
this._transformNode.position.z = .7;
this._transformNode.position.y = -.3;
const ray = scene.activeCamera.getForwardRay(1);
ray.direction.y = 0;
const fpos = scene.activeCamera.globalPosition.clone().add(ray.direction.scale(1));
this._transformNode.position = fpos;
this._transformNode.position.y -= .4;
this._transformNode.lookAt(scene.activeCamera.globalPosition);
this._transformNode.rotate(Vector3.Up(), Math.PI);
this._transformNode.setParent(platform);
this._transformNode.rotation.z = 0;
}
public get mesh(): AbstractMesh {

201
src/users/userManager.ts Normal file
View File

@ -0,0 +1,201 @@
import {AbstractMesh, MeshBuilder, Observable} from "@babylonjs/core";
import {UserModelType} from "./userTypes";
import {getMe} from "../util/me";
import {DefaultScene} from "../defaultScene";
import {vectoxys, xyztovec} from "../diagram/functions/vectorConversion";
import Peer, {PeerOptions} from "peer-lite";
export class UserManager {
private readonly _onUserObservable: Observable<UserModelType>;
private readonly _me: string;
private _platform: AbstractMesh;
private _myOldModel: UserModelType;
private _turn_credentials: any;
constructor(onUserObservable: Observable<UserModelType>) {
//this.createRTCConnection();
//this.createRTCConnection();
//data.send('test');
this._me = getMe();
this._onUserObservable = onUserObservable;
const scene = DefaultScene.Scene;
let tick = 0;
scene.onAfterRenderObservable.add(() => {
tick++;
if (!this._platform) {
const platform = scene.getMeshById('platform');
if (platform) {
this._platform = platform;
}
} else {
if (tick % 10 == 0) {
if (!this._myOldModel ||
(this._myOldModel.base.position.x != this._platform.absolutePosition.x ||
this._myOldModel.base.position.y != this._platform.absolutePosition.y ||
this._myOldModel.base.position.z != this._platform.absolutePosition.z)) {
const me: UserModelType = {
id: this._me,
name: 'me',
type: 'user',
base: {
position: {x: 0, y: 0, z: 0},
rotation: {x: 0, y: 0, z: 0}
}
}
console.log(me);
me.base.position = vectoxys(this._platform.absolutePosition);
me.base.rotation = vectoxys(this._platform.absoluteRotationQuaternion.toEulerAngles());
this._myOldModel = me;
this._onUserObservable.notifyObservers(me);
}
}
}
});
this._onUserObservable.add((evt: UserModelType) => {
if (evt.id != this._me) {
const userMesh: AbstractMesh = scene.getMeshById(evt.id);
if (!userMesh) {
const newMesh = MeshBuilder.CreateIcoSphere(evt.id, {radius: 0.1}, scene);
newMesh.position = xyztovec(evt.base.position);
console.log('creating mesh for user', evt);
// create mesh
} else {
userMesh.position = xyztovec(evt.base.position);
console.log('updating mesh for user', evt);
// update mesh
}
}
console.log(evt);
});
const me: UserModelType = {
id: this._me,
name: 'me',
type: 'user',
base: {
position: {x: 0, y: 0, z: 0},
rotation: {x: 0, y: 0, z: 0}
}
}
this._onUserObservable.notifyObservers(me);
}
private async createRTCConnection2() {
const credentials =
{
'iceServers': [{
'urls': [
"stun:stun.cloudflare.com:3478",
"turn:turn.cloudflare.com:3478?transport=udp",
"turn:turn.cloudflare.com:3478?transport=tcp",
"turns:turn.cloudflare.com:5349?transport=tcp"
],
'username': "e56a6c7ad64e4d9f7ce1288cf716f4b0dd762053a748f4eecc377010de4bc59e295ad2776281a672e8f5c1c70b0d78e0",
'credential': "07963a124f189e6e0761c88b87fbf7d082701245db3cc4318b0973247964ee1a878def7a4ce4f48da259274bf7183bfd"
}]
};
const options: PeerOptions = {
enableDataChannels: true,
config: credentials,
id: this._me,
}
const peer = new Peer(
options);
peer.on('signal', async (description) => {
console.log(description);
});
peer.on('connecting', async () => {
console.log('connected');
});
peer.on('onicecandidates', async (candidate) => {
console.log(candidate);
})
peer.addDataChannel('test');
peer.send('test');
peer.init();
peer.start();
const channel = peer.getDataChannel('test');
channel.onopen = (evt) => {
console.log(evt);
channel.send(
'test');
};
channel.onmessage = (evt) => {
console.log(evt);
}
}
private async createRTCConnection() {
const credentials =
{
'iceServers': [{
'urls': [
"stun:stun.cloudflare.com:3478",
"turn:turn.cloudflare.com:3478?transport=udp",
"turn:turn.cloudflare.com:3478?transport=tcp",
"turns:turn.cloudflare.com:5349?transport=tcp"
],
'username': "e56a6c7ad64e4d9f7ce1288cf716f4b0dd762053a748f4eecc377010de4bc59e295ad2776281a672e8f5c1c70b0d78e0",
'credential': "07963a124f189e6e0761c88b87fbf7d082701245db3cc4318b0973247964ee1a878def7a4ce4f48da259274bf7183bfd"
}]
};
const rtc = new RTCPeerConnection(credentials);
rtc.onconnectionstatechange = (evt) => {
console.log(evt);
};
const data = rtc.createDataChannel('test');
data.onopen = (evt) => {
console.log(evt);
data.send('hello');
};
rtc.onsignalingstatechange = (evt) => {
console.log(evt);
}
const offer = await rtc.createOffer(
{
iceRestart: true,
offerToReceiveAudio: true,
offerToReceiveVideo: true
});
//const remote = await rtc.setRemoteDescription(offer);
await rtc.setLocalDescription(offer);
//await rtc.setRemoteDescription(offer);
//const answer = await rtc.createAnswer();
//console.log(answer);
console.log('here');
rtc.addEventListener('icecandidate', (evt) => {
rtc.addIceCandidate(evt.candidate).then(() => {
console.log(evt);
}).catch(() => {
});
})
//await rtc.setLocalDescription(answer);
//await rtc.setRemoteDescription(answer);
}
}
function onCatch(err) {
console.log(err);
}

27
src/users/userTypes.ts Normal file
View File

@ -0,0 +1,27 @@
export type XYZType = {
x: number,
y: number,
z: number
}
export type UserModelType = {
id: string,
name: string,
type: string,
state?: string,
base: {
position: XYZType,
rotation: XYZType
}
head?: {
position: XYZType,
rotation: XYZType
}
rightHand?: {
position: XYZType,
rotation: XYZType
}
leftHand?: {
position: XYZType,
rotation: XYZType
}
}

View File

@ -12,6 +12,8 @@ import {buildQuestLink} from "./util/functions/buildQuestLink";
import {exportGltf} from "./util/functions/exportGltf";
import {DefaultScene} from "./defaultScene";
import {Introduction} from "./tutorial/introduction";
import {UserManager} from "./users/userManager";
const webGpu = false;
@ -47,12 +49,14 @@ export class VrApp {
const scene = new Scene(engine);
DefaultScene.Scene = scene;
scene.ambientColor = new Color3(.1, .1, .1);
//log.resetLevel();
//log.setDefaultLevel('error');
await this.initialize(scene);
engine.runRenderLoop(() => {
scene.render();
});
}
public async initialize(scene: Scene) {
setMainCamera(scene);
@ -91,9 +95,12 @@ function setMainCamera(scene: Scene) {
async function initDb(diagramManager: DiagramManager) {
const db = new PouchdbPersistenceManager();
const userManager = new UserManager(db.onUserObservable);
db.setDiagramManager(diagramManager);
await db.initialize();
}
function initEnvironment(diagramManager: DiagramManager, spinner: Spinner) {