src/app/models/cabri-integration-jeudekim.ts
constructor(cabriService: CabriDataService, globalService: GlobalService, _ngZone: any, page: any, renderer: Renderer2)
|
| onBabylonReady |
onBabylonReady()
|
|
Returns:
void
|
| globalParamsChanged |
globalParamsChanged()
|
|
Settings params changed
Returns:
void
|
| unregisterRotation |
unregisterRotation()
|
|
Returns:
void
|
| resetScene |
resetScene(restart: boolean)
|
|
Returns:
void
|
| awardAnimation |
awardAnimation()
|
|
Delete objects on Scene and run mathia award animation
Returns:
any
|
| updateObjectsToRotate |
updateObjectsToRotate()
|
|
Set objects on circle for solar rotation
Returns:
void
|
| getCircle |
getCircle(forceWait: boolean)
|
|
Get circle and create it if not exist
Returns:
void
|
| waitObjectsReady |
waitObjectsReady()
|
|
Verify all objects are ready
Returns:
any
|
| setWallTextures |
setWallTextures(show: boolean)
|
|
Set wall texture.
Parameters :
Returns:
void
|
| getCenter |
getCenter(meshes: any)
|
|
Merge meshes to calculte their center
Parameters :
Returns:
void
|
| hideAllSolids |
hideAllSolids()
|
|
Hide all solids
Returns:
void
|
| showAllSolids |
showAllSolids()
|
|
Show all solids
Returns:
void
|
| toggleSolids |
toggleSolids(key: any, visibility: any)
|
|
Toggle solids
Parameters :
Returns:
void
|
| hideObjectTofind |
hideObjectTofind(id: any)
|
|
Find meshes and hide them.
Parameters :
Returns:
void
|
| blinkObject |
blinkObject(id: any)
|
|
Visibility animation on solid.
Parameters :
Returns:
void
|
| stopBlink |
stopBlink(id: any)
|
|
Stop blink animation
Parameters :
Returns:
void
|
| getSolidKey |
getSolidKey(id: any)
|
|
Returns:
void
|
| onSolids |
onSolids(key: any, callback: any)
|
|
Callback on all key solids
Parameters :
Returns:
void
|
| onSolid |
onSolid(id: any, callback: any, counter: number)
|
|
Callback on solid "cabri" id (set in cabri auteur)
Parameters :
Returns:
void
|
| updateCabriPosition |
updateCabriPosition(holoMode: string)
|
|
Update DOM Cabri elements
Parameters :
Returns:
any
|
| saveDom |
saveDom()
|
|
Returns:
void
|
| checkActivityChange |
checkActivityChange()
|
|
Returns:
boolean
|
| restoreDom |
restoreDom(activityChange: boolean)
|
|
Returns:
void
|
| startRender |
startRender(force: boolean)
|
|
Custom start/Stop render to not start/stop renderLoop (rotation objects)
Returns:
void
|
| stopRender |
stopRender(force: boolean)
|
|
Custom start/Stop render to not start/stop renderLoop (rotation objects)
Returns:
void
|
| hideWalls |
hideWalls()
|
|
Returns:
void
|
| showWalls |
showWalls()
|
|
Returns:
void
|
| setCameraDefaultPosition |
setCameraDefaultPosition()
|
|
Returns:
void
|
| _ngZone |
_ngZone: |
| Public allFacets |
allFacets: |
| Public allPolyhedrons |
allPolyhedrons: |
| Public blackListPolyhedron |
blackListPolyhedron: |
|
Ids des murs |
| cabriService |
cabriService: |
| Public circle |
circle: |
| Private circleClone |
circleClone: |
| Public currentFPS |
currentFPS: |
| Public divider |
divider: |
Default value: 0
|
| globalService |
globalService: |
| Public isCordova |
isCordova: |
| ngZone |
ngZone: |
| page |
page: |
| renderer |
renderer: |
| rotationOnFrameRender |
rotationOnFrameRender: |
| Public rotationReady |
rotationReady: |
Default value: false
|
| saveCircleQuaternion |
saveCircleQuaternion: |
| Public wallTexture |
wallTexture: |
import { CabriIntegration } from "./cabri-integration";
import { CabriDataService } from "../services/cabri-data.service";
import { GlobalService } from "../services/global.service";
import { Platform } from "@ionic/angular";
import { Renderer2 } from "@angular/core";
declare var BABYLON;
declare var window: {
store: any;
document: any;
innerWidth: any;
innerHeight: any;
outerWidth: any;
outerHeight: any;
wallTexture: any;
Globals: any;
dispatchEvent: any;
};
export class CabriIntegrationJeudekim extends CabriIntegration {
public isCordova: boolean;
ngZone: any;
public wallTexture;
saveCircleQuaternion: any;
constructor(
public cabriService: CabriDataService,
public globalService: GlobalService,
public _ngZone,
public page,
public renderer: Renderer2
) {
super(cabriService, globalService, _ngZone, page, renderer);
this.cabriRenderStarted = true;
this.page = page;
}
public allFacets = [];
public allPolyhedrons = [];
/**
* Ids des murs
*/
public blackListPolyhedron = [82992, 83023, 83029, 83036];
public circle;
public rotationReady = false;
public divider = 0;
public currentFPS;
private circleClone;
async onBabylonReady() {
try {
await super.onBabylonReady();
this.divider = 0;
await this.timeOut(1000); // be sure everuything is ready @TODO imprive
// remove not used holo cabri objects
if (this.holoCameras && (!window.Globals.HoloFaces || window.Globals.HoloFaces === 1)) {
this.holoCameras.rttX.dispose();
this.holoCameras.rttZ.dispose();
this.holoCameras.rtt_x.dispose();
this.holoCameras.BKGX.dispose();
this.holoCameras.BKGZ.dispose();
this.holoCameras.BKGx.dispose();
}
// change camera angle
(this.scene as any).CABRI.unlockOrientation();
if (this.page.cabriService.holoMode === "0") {
this.camera.lowerBetaLimit = this.camera.upperBetaLimit = this.camera.beta = 1.25;
}
// create wall textures for later : see setWallTextures
this.wallTexture = new BABYLON.StandardMaterial("wallTexture", this.scene);
this.wallTexture.diffuseTexture = new BABYLON.Texture("assets/babylon/texnuage.png", this.scene);
this.wallTexture.diffuseTexture.hasAlpha = true;
this.wallTexture.opacityTexture = this.wallTexture.diffuseTexture;
this.wallTexture.useAlphaFromDiffuseTexture = true;
this.wallTexture.alphaMode = 2;
await this.setWallTextures(false);
if (this.page.cabriService.mirrorMode) {
this.hideWalls();
const disc = await this.getCabriMesh(64575, "f_circle");
disc.visibility = 0;
}
this.circle = await this.getCircle();
if (this.page.restore && this.cabriService.currentSavedDom === "jeudekim") {
this.circleClone = await this.getMesh("savedCircle");
} else {
if (!this.circle) {
this.circle = await this.getCircle(true);
}
if (this.page.cabriService.mirrorMode) {
this.circle.visibility = 0;
}
this.circleClone = this.circle.clone();
this.circleClone.layerMask = null;
this.circleClone.id = "savedCircle";
}
// register Babylon animation
this.scene.registerAfterRender(this.rotationOnFrameRender);
} catch (error) {
this.page.stopLoader();
throw error;
}
}
/**
* Settings params changed
*/
async globalParamsChanged(){
const disc = await this.getCabriMesh(64575, "f_circle");
const circle = await this.getCircle(true);
if(disc){
disc.visibility = this.page.cabriService.mirrorMode ? 0 : 1;
if(circle){
this.circleClone = circle;
circle.visibility = this.page.cabriService.mirrorMode ? 0 : 1;
}
}
}
rotationOnFrameRender = () => {
if ((this.divider < 1000 && this.divider % 30 === 0) || this.divider % 600 === 0) {
this.currentFPS = (this.scene as any)._engine.getFps();
}
if (this.rotationReady) {
this.circle.rotate(BABYLON.Axis.Y, (0.005 * 60) / this.currentFPS, BABYLON.Space.WORLD);
this.allFacets.forEach(polyhedron => {
polyhedron.forEach(f => {
if (!f.isDisposed()) {
f.rotate(BABYLON.Axis.Y, (0.01 * 60) / this.currentFPS, BABYLON.Space.WORLD);
}
});
});
}
this.divider++;
};
unregisterRotation() {
if (this.scene) {
this.scene.unregisterAfterRender(this.rotationOnFrameRender);
}
}
resetScene(restart = false) {
// stop rotation
this.rotationReady = false;
// delete all objects (cabri recreate them)
this.allFacets.forEach(polyhedron => {
polyhedron.forEach(mesh => {
mesh.dispose();
});
});
this.allPolyhedrons.forEach(polyhedron => {
polyhedron.dispose();
});
// delete circle (prevent bug of futur mesh.setParent(circle))
// don't dispose on restartActivity / dispose() not a function error
if (this.circle && !restart) {
this.circle.dispose();
this.circle = null;
}
if (!this.circle) {
this.circle = this.getCircle();
}
}
/**
* Delete objects on Scene and run mathia award animation
*/
awardAnimation(): Promise<void> {
return new Promise(async (resolve, reject) => {
this.resetScene();
this.page.kimAnimSuccessRunning = true;
this.cabriService.hideMathia = true;
this.page.detectChanges();
window.dispatchEvent(new Event("focus"));
this.loadMathia(() => {
this.page.kimAnimSuccessRunning = false;
this.cabriService.hideMathia = false;
this.page.detectChanges();
resolve();
});
});
}
/**
* Set objects on circle for solar rotation
* And set PivotPoint for planetary rotation
*/
async updateObjectsToRotate() {
if (this.page.isActivePage()) {
// verify all objects are ready
await this.waitObjectsReady();
// get new circle
this.circle = await this.getCircle(true);
// stop rotation
this.rotationReady = false;
// set all facets ready for rotations
this.allFacets = [];
for (const k in this.cabriObjects) {
if (this.cabriObjects.hasOwnProperty(k)) {
const o = this.cabriObjects[k];
if (o.type === "polyhedron" && this.blackListPolyhedron.indexOf(o.id) === -1) {
console.log(o);
this.allFacets[o.id] = [];
const mergeFacets = [];
for (const i in this.cabriObjects) {
if (this.cabriObjects.hasOwnProperty(i)) {
const facet = this.cabriObjects[i];
if (String(facet.polyhedronId) === String(k)) {
const cabriMesh = await this.getCabriMesh(facet.id);
// set mesh on circle and keep same position
cabriMesh.setParent(this.circle);
if (this.page.cabriService.holoMode === "0" && this.currentFPS > 30 && !this.page.globalService.isIos) {
// set mesh edges
cabriMesh.enableEdgesRendering(0.95, true);
cabriMesh.edgesWidth = 7.0;
cabriMesh.edgesColor = new BABYLON.Color4(1, 1, 1, 1);
}
mergeFacets.push(cabriMesh);
this.allFacets[o.id].push(cabriMesh);
}
}
}
if (mergeFacets.length > 0) {
const mergeFacetsClean = mergeFacets.filter(f => f.name !== "triangulatedPolygon" && !f.isDisposed());
const info = this.getCenter(mergeFacetsClean);
mergeFacets.forEach(f => {
f.setPivotPoint(new BABYLON.Vector3(info.x, info.y, info.z));
});
}
}
if (o.type === "sphere" || o.type === "cylinder" || o.type === "cone") {
const cabriMesh = await this.getCabriMesh(o.id);
if (this.page.cabriService.holoMode === "0" && this.currentFPS > 30 && !this.page.globalService.isIos) {
if (o.type === "sphere" || o.type === "cone") {
cabriMesh.outlineColor = new BABYLON.Color3(1, 1, 1);
cabriMesh.renderOutline = true;
// cabriMesh.outlineWidth = 4.0;
if (o.type === "cone") {
// set mesh edges
cabriMesh.enableEdgesRendering(0.9, true);
cabriMesh.edgesWidth = 4.0;
cabriMesh.edgesColor = new BABYLON.Color4(1, 1, 1, 1);
}
} else if (o.type === "cylinder") {
// set mesh edges
cabriMesh.enableEdgesRendering(0.9, true);
cabriMesh.edgesWidth = 4.0;
cabriMesh.edgesColor = new BABYLON.Color4(1, 1, 1, 1);
}
}
// set mesh on circle and keep same position
const savePosition = cabriMesh.getAbsolutePosition();
cabriMesh.parent = this.circle;
cabriMesh.setAbsolutePosition(savePosition);
const info = cabriMesh.getBoundingInfo().boundingBox.centerWorld;
cabriMesh.setPivotMatrix(
BABYLON.Matrix.Translation(savePosition.x - info.x, savePosition.y - info.y, savePosition.z - info.z)
);
this.allPolyhedrons.push(cabriMesh);
}
}
}
// start rotation
this.rotationReady = true;
}
}
/**
* Get circle and create it if not exist
*/
async getCircle(forceWait = false) {
if (this.page.isActivePage()) {
let circle = await this.getCabriMesh(64575, "circle", forceWait);
if (!circle) {
const circleClone = this.getMesh("savedCircle");
if (circleClone) {
circle = circleClone.clone();
circle.id = 64575;
circle.name = "circle";
circle.object = {
type: "circle",
id: 64575
};
circle.layerMask = 0x10000000;
}
}
return circle;
}
}
/**
* Verify all objects are ready
*/
waitObjectsReady(): Promise<void> {
return new Promise(async resolve1 => {
let count = 0;
const totalNeeded =
this.page.objectsCount.cube +
this.page.objectsCount.slab +
this.page.objectsCount.sphere +
this.page.objectsCount.pyramid +
this.page.objectsCount.cone +
this.page.objectsCount.cylinder;
while (count !== totalNeeded && this.page.isActivePage()) {
count = 0;
for (const k in this.cabriObjects) {
if (this.cabriObjects.hasOwnProperty(k)) {
const o = this.cabriObjects[k];
if (
(o.type === "polyhedron" || o.type === "sphere" || o.type === "cone" || o.type === "cylinder") &&
this.blackListPolyhedron.indexOf(o.id) === -1
) {
count++;
}
}
}
console.log(count + "===" + totalNeeded);
await this.timeOut(100);
}
// all objects present
resolve1();
});
}
/**
* Set wall texture.
* @param show true/false
*/
async setWallTextures(show = true) {
let countWall = 0;
for (const k in this.cabriObjects) {
if (this.cabriObjects.hasOwnProperty(k)) {
const o = this.cabriObjects[k];
if (o.type === "polyhedron" && this.blackListPolyhedron.indexOf(o.id) > -1) {
countWall++;
// hide walls
for (const i in this.cabriObjects) {
if (this.cabriObjects.hasOwnProperty(i)) {
const facet = this.cabriObjects[i];
if (String(facet.polyhedronId) === String(o.id)) {
const cabriMesh = await this.getCabriMesh(facet.id);
cabriMesh.visibility = 0;
}
}
}
// set textures
for (const i in this.cabriObjects) {
if (this.cabriObjects.hasOwnProperty(i)) {
const facet = this.cabriObjects[i];
if (String(facet.polyhedronId) === String(o.id)) {
const cabriMesh = await this.getCabriMesh(facet.id);
if (countWall === 1) {
cabriMesh.renderingGroupId = 2;
}
cabriMesh.material = this.wallTexture;
facet.facetmaterial = this.wallTexture;
cabriMesh.visibility = 1;
}
}
}
// show walls
if (show) {
for (const i in this.cabriObjects) {
if (this.cabriObjects.hasOwnProperty(i)) {
const facet = this.cabriObjects[i];
if (String(facet.polyhedronId) === String(o.id)) {
const cabriMesh = await this.getCabriMesh(facet.id);
cabriMesh.visibility = 1;
}
}
}
}
}
}
}
}
/**
* Merge meshes to calculte their center
* @param meshes meshes to find center
*/
getCenter(meshes) {
const mergedFacets = BABYLON.Mesh.MergeMeshes(meshes, false);
const info = mergedFacets.getBoundingInfo().boundingBox.centerWorld;
mergedFacets.dispose();
return info;
}
/**
* Hide all solids
*/
async hideAllSolids() {
await this.toggleSolids("cube", 0);
await this.toggleSolids("pave", 0);
await this.toggleSolids("boule", 0);
await this.toggleSolids("pyr", 0);
await this.toggleSolids("cone", 0);
await this.toggleSolids("cyl", 0);
}
/**
* Show all solids
*/
async showAllSolids() {
await this.toggleSolids("cube", 1);
await this.toggleSolids("pave", 1);
await this.toggleSolids("boule", 1);
await this.toggleSolids("pyr", 1);
await this.toggleSolids("cone", 1);
await this.toggleSolids("cyl", 1);
}
/**
* Toggle solids
* @param key cube, pave, boule, pyr or cone
* @param visibility force visibility 0 or 1
*/
async toggleSolids(key, visibility = null) {
await this.onSolids(key, cabriMesh => {
if (visibility !== null) {
cabriMesh.visibility = visibility;
} else {
cabriMesh.visibility = cabriMesh.visibility === 1 ? 0 : 1;
}
});
}
/**
* Find meshes and hide them.
* @param id solid ID
*/
async hideObjectTofind(id) {
const callback = mesh => {
mesh.visibility = 0;
};
const key = this.getSolidKey(id);
console.log("hideObjectTofind " + key);
await this.onSolid(key, callback);
}
/**
* Visibility animation on solid.
* @param id solid ID
*/
async blinkObject(id) {
const callback = mesh => {
if (mesh) {
const blinkSolid = new BABYLON.Animation(
"blinksolid",
"visibility",
30,
BABYLON.Animation.ANIMATIONTYPE_FLOAT,
BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE
);
// An array with all animation keys
const keys = [];
keys.push({ frame: 0, value: 1 });
keys.push({ frame: 30, value: 0 });
keys.push({ frame: 60, value: 1 });
blinkSolid.setKeys(keys);
mesh.animations = [];
mesh.animations.push(blinkSolid);
this.scene.beginAnimation(mesh, 0, 60, true);
}
};
const key = this.getSolidKey(id);
console.log("blinkObject " + key);
await this.onSolid(key, callback);
}
/**
* Stop blink animation
* @param id Solid id
*/
async stopBlink(id) {
const callback = mesh => {
this.scene.stopAnimation(mesh);
mesh.visibility = 1;
};
const key = this.getSolidKey(id);
await this.onSolid(key, callback);
}
getSolidKey(id) {
let number, key;
if (id < 4) {
number = id;
key = "s-cube-" + number;
} else if (id < 7) {
number = id - 3;
key = "s-pave-" + number;
} else if (id < 10) {
number = id - 6;
key = "s-boule-" + number;
} else if (id < 13) {
number = id - 9;
key = "s-pyr-" + number;
} else if (id < 16) {
number = id - 12;
key = "s-cone-" + number;
} else if (id < 19) {
number = id - 15;
key = "s-cyl-" + number;
}
return key;
}
/**
* Callback on all key solids
* @param key cube, pave, boule, pyr, cone
* @param callback callback
*/
async onSolids(key, callback) {
await this.onSolid("s-" + key + "-1", callback);
await this.onSolid("s-" + key + "-2", callback);
await this.onSolid("s-" + key + "-3", callback);
}
/**
* Callback on solid "cabri" id (set in cabri auteur)
* @param id solid id
* @param callback callback
*/
async onSolid(id, callback, counter = 0) {
let found = false;
id = window.store.getters.cps.cpsGetObjectIdByName(id);
for (const k in this.cabriObjects) {
if (this.cabriObjects.hasOwnProperty(k)) {
const o = this.cabriObjects[k];
if (o.type === "polyhedron" && String(id) === String(o.id)) {
for (const i in this.cabriObjects) {
if (this.cabriObjects.hasOwnProperty(i)) {
const facet = this.cabriObjects[i];
if (String(facet.polyhedronId) === String(o.id)) {
const cabriMesh = await this.getCabriMesh(facet.id);
callback(cabriMesh);
found = true;
}
}
}
} else if (String(id) === String(o.id)) {
const cabriMesh = await this.getCabriMesh(o.id);
callback(cabriMesh);
found = true;
}
}
}
if (!found && counter < 100 && !this.page.scenario.skipSequence) {
counter++;
await this.timeOut(100);
await this.onSolid(id, callback, counter);
} else if (!found) {
console.error("Solid " + id + " NOT found ! (" + counter + ")");
}
}
/**
* Update DOM Cabri elements
* @param holoMode Holo mode
* @param platform Platform
*/
async updateCabriPosition(holoMode: string = null): Promise<void> {
return super.updateCabriPosition(holoMode, "jeudekim");
}
saveDom() {
super.saveDom();
this.cabriService.currentSavedDom = "jeudekim";
}
checkActivityChange(): boolean {
return true;
const activityChange =
this.cabriService.currentSavedDom !== "jeudekim" ||
this.cabriService.savedDomHoloMode !== this.cabriService.holoMode ||
this.cabriService.savedDomMirrorMode !== this.cabriService.mirrorMode;
// console.error("checkActivityChange = " + activityChange);
return activityChange;
}
restoreDom(activityChange: boolean = false) {
window.Globals.HoloFaces = null;
super.restoreDom();
if (activityChange) {
// clean all custom elements in #page-div
if (window.document.querySelector("#page-div #operationWrapper")) {
window.document.querySelector("#page-div").removeChild(window.document.querySelector("#page-div #operationWrapper"));
}
if (window.document.querySelector("#page-div #operationWrapperCordova")) {
window.document.querySelector("#page-div").removeChild(window.document.querySelector("#page-div #operationWrapperCordova"));
}
}
this.startRender();
}
/**
* Custom start/Stop render to not start/stop renderLoop (rotation objects)
*/
async startRender(force = false) {
if (force) {
super.startRender(true);
}
if (this.cabriRenderStarted === false || force) {
window.store.getters.cabri.Cps.setActiveState(true);
console.log("%c RENDER STARTED (KIM)", "background: greenforest; color black");
this.cabriRenderStarted = true;
}
}
/**
* Custom start/Stop render to not start/stop renderLoop (rotation objects)
*/
stopRender(force = false) {
if (force) {
super.stopRender();
}
console.log("%c RENDER STOPPED (KIM)", "background: orange; color yellow");
window.store.getters.cabri.Cps.setActiveState(false);
this.cabriRenderStarted = false;
}
async hideWalls() {
if (this.page.isActivePage()) {
for (const k in this.cabriObjects) {
if (this.cabriObjects.hasOwnProperty(k)) {
const o = this.cabriObjects[k];
if (o.type === "polyhedron" && this.blackListPolyhedron.indexOf(o.id) > -1) {
for (const i in this.cabriObjects) {
if (this.cabriObjects.hasOwnProperty(i)) {
const facet = this.cabriObjects[i];
if (String(facet.polyhedronId) === String(o.id)) {
const cabriMesh = await this.getCabriMesh(facet.id);
cabriMesh.visibility = 0;
console.error(cabriMesh);
}
}
}
}
}
}
}
}
async showWalls() {
if (this.page.isActivePage()) {
for (const k in this.cabriObjects) {
if (this.cabriObjects.hasOwnProperty(k)) {
const o = this.cabriObjects[k];
if (o.type === "polyhedron" && this.blackListPolyhedron.indexOf(o.id) > -1) {
for (const i in this.cabriObjects) {
if (this.cabriObjects.hasOwnProperty(i)) {
const facet = this.cabriObjects[i];
if (String(facet.polyhedronId) === String(o.id)) {
const cabriMesh = await this.getCabriMesh(facet.id);
cabriMesh.visibility = 1;
}
}
}
}
}
}
}
}
setCameraDefaultPosition() {
if (!this.camera) {
this.camera = window.store.getters.cabri.Camera2D3D;
}
this.initialCameraPosition = { radius: 50, alpha: -Math.PI / 2, beta: (7 * Math.PI) / 18 };
this.restoreCamera();
}
}