Files
Maninghem/js/objects.js
2024-01-18 15:18:18 +01:00

1182 lines
49 KiB
JavaScript
Executable File

import {
COLOR_ARRAY,
glassMaterial,
windowMaterial,
doorMaterial,
roofMaterial,
garageDoorMaterial,
wallMaterial,
pignonMaterial,
floorMaterial,
SOLP_Material,
SOLE_1_Material,
SOLE_2_Material,
SOLT_Material,
MPL_Material,
MPI_Material,
MPE_Material,
MF1d_Material,
MF1g_Material,
MF2_Material,
MPEF_Material,
MPF_Material,
MPG1_Material,
MPG2_Material,
PEXT_Material,
PINT_Droite_Material,
PINT_Gauche_Material,
createText
} from "./materials.js"
import {
log,
alerte,
mergeGroups,
extraireNomTravee,
extraireFace,
retirerObjetModifiable,
initialiserScoresVT,
recalculerConstructions,
simulerCalculConstructions,
modifierIncrustation,
hidePignonIncrustations,
incrusterCotes,
restaurerPrefsUtilisateur,
rechercherFaceOpposee
} from "./main.js"
import {
unSelect
} from "./gui.js"
function degrees_to_radians(degrees) {
var pi = Math.PI;
return degrees * (pi / 180);
}
export function recreerTrappes() {
for (var travee in tableauTravees) {
if (tableauTravees[travee].rangDansConstruction == 1) {
selectionnerSolivage(travee, "SOLT_bc");
}
}
}
export function supprimerToutesOuvertures() {
// Supprime toutes les ouvertures du projet (fenêtres, solivages, ...), par exemple lors de l'ajout d'une travée ou son décalage.
var nbObjets = objetsModifiables.length;
var aSupprimer = new Array();
for (var i = 0; i < nbObjets; i++) {
if (objetsModifiables[i].name.includes('Ouverture')) {
aSupprimer.push(objetsModifiables[i].name);
}
}
for (var i = 0; i < aSupprimer.length; i++) {
supprimerOuverture(aSupprimer[i]);
}
inventaire["MPE"] = inventaire["MPF"] = inventaire["MF1"] = inventaire["MF2"] = inventaire["MPG1"] = inventaire["MPG2"] = inventaire["MPEF"] = inventaire["MPI"] = 0;
inventaire["MF1R"] = inventaire["MF2R"] = inventaire["MPER"] = 0;
// On supprime également tous les solivages
for (var i = 1; i <= nbTravees; i++) {
var nomTravee = PREFIXE_TRAVEE + i;
selectionnerSolivage(nomTravee, "SOLP");
}
inventaire["SOLE"] = inventaire["SOLT"] = 0;
inventaire["SOLP"] = nbTravees;
nbOuvertures = 0;
}
export function supprimerOuverture(nomObjet) {
// Supprimer une ouverture (hors solivage) bien spécifique, lorsque demandé depuis l'IHM
var travee = extraireNomTravee(nomObjet);
var face = extraireFace(nomObjet);
var objet = scene.getObjectByName(nomObjet);
var nomModule = nomObjet.substr(nomObjet.lastIndexOf(' ') + 1);
// Pour le cas particulier du portique intérieur, on raffiche la cloison précédemment masquée.
if (nomObjet.includes("PO")) {
var portique = scene.getObjectByName(extraireNomTravee(nomObjet) + ">" + extraireFace(nomObjet));
portique.visible = true;
}
// Il faut supprimer l'objet à l'IHM, ainsi que sa référence dans l'incrustation ...
scene.getObjectByName(travee).remove(objet);
modifierIncrustation(travee, face, PRODUITS['MU']['codeModule']);
nbOuvertures--;
// recalculer les scores VT de la travée concernée...
tableauTravees[travee]['nb_ouvertures_' + face]--;
tableauTravees[travee]['vt_' + face] = PRODUITS['MU']['VT'];
// Si l'on est en vue "Ossature bois", il faut également rafraichir la texture du mur sur lequel on vient de supprimer l'ouverture.
var modeOssatureBois = $("span:contains('ossatureBois')").parent().find("input[type='checkbox']").prop('checked');
if (modeOssatureBois) {
var mur = nomObjet.substring(0, nomObjet.lastIndexOf('>'));
scene.getObjectByName(mur).material = MPL_Material;
objetSelectionne = travee + ">" + face;
}
// et enfin, déselectionner l'objet.
retirerObjetModifiable(objet.name);
if (!modeOssatureBois) objetSelectionne = '';
unSelect();
if (modeOssatureBois) objetSelectionne = '';
// On met à jour l'inventaire du projet.
inventaire[PRODUITS[nomModule].codeModule]--;
inventaire["MPL"]++;
if (DEBUG) {
log('tableauTravee APRES supprimerOuverture :');
log(tableauTravees);
}
}
export function creerOuverture(nomTravee, face, typeOuverture, forcerIncrustation = false) {
var windowGrp = new THREE.Group();
var largeur, hauteur, epaisseur, elevation, decalageX;
var nbPanneaux = 1;
var murInterieur = false;
// On récupère d'abord les caractéristiques de l'ouverture à créer
largeur = PRODUITS[typeOuverture]['largeur'];
hauteur = PRODUITS[typeOuverture]['hauteur'];
elevation = PRODUITS[typeOuverture]['elevation'];
epaisseur = PRODUITS[typeOuverture]['epaisseur'];
decalageX = PRODUITS[typeOuverture]['decalageX'];
var dernierRang = 2;
if ((face.includes('PG') && tableauTravees[nomTravee]['rangDansConstruction'] != 1) ||
(face.includes('PD') && tableauTravees[nomTravee]['rangDansConstruction'] != dernierRang)) {
murInterieur = true;
}
// Le portique intérieur est un cas bien particulier : on supprime la cloison et on la remplace pour une ouverture ayant le même matériel qu'un mur.
if (typeOuverture == 'PO') {
var facade = scene.getObjectByName(nomTravee + ">" + face);
facade.visible = false;
var portionMur = new THREE.Mesh(new THREE.BoxGeometry((LONGUEUR_TRAVEE / 2), 4, EPAISSEUR_MUR), wallMaterial);
portionMur.name = nomTravee + '>' + face + '>Ouverture ' + typeOuverture + '>Portique';
scene.getObjectByName(nomTravee + ">" + face + ">Incrustation").userData = {
customVisibility: true
};
windowGrp.add(portionMur);
} else { // Ouvertures "classiques"
if (typeOuverture === 'F2' || typeOuverture === 'PF' || typeOuverture === 'F2R') nbPanneaux = 2;
// On constitue en premier le chassis
var windowGeometry = new THREE.Shape();
windowGeometry.moveTo(0, 0);
windowGeometry.lineTo(0, hauteur);
windowGeometry.lineTo(largeur, hauteur);
windowGeometry.lineTo(largeur, 0);
windowGeometry.lineTo(0, 0);
switch (nbPanneaux) {
case 1:
var windowHole = new THREE.Shape();
windowHole.moveTo(.5, .5);
windowHole.lineTo(.5, hauteur - .5);
windowHole.lineTo(largeur - .4, hauteur - .5);
windowHole.lineTo(largeur - .4, .5);
windowHole.lineTo(.5, .5);
windowGeometry.holes.push(windowHole);
break;
default: // Normalement 2
var windowHole1 = new THREE.Shape();
windowHole1.moveTo(.5, .5);
windowHole1.lineTo(.5, hauteur - .5);
windowHole1.lineTo((largeur / 2) - .2, hauteur - .5);
windowHole1.lineTo((largeur / 2) - .2, .5);
windowHole1.lineTo(.5, .5);
windowGeometry.holes.push(windowHole1);
var windowHole2 = new THREE.Shape();
windowHole2.moveTo((largeur / 2) + .2, 0.5);
windowHole2.lineTo((largeur / 2) + .2, hauteur - .5);
windowHole2.lineTo(largeur - .5, hauteur - .5);
windowHole2.lineTo(largeur - .5, 0.5);
windowHole2.lineTo((largeur / 2) + .2, 0.5);
windowGeometry.holes.push(windowHole2);
break;
}
var extrudeSettings = {
steps: 4,
depth: epaisseur,
bevelEnabled: false
};
var windowFrame = new THREE.Mesh(new THREE.ExtrudeBufferGeometry(windowGeometry, extrudeSettings), windowMaterial);
windowFrame.position.set(-(largeur / 2) + .5, -(hauteur / 2) + .5, -(epaisseur / 2));
windowFrame.name = 'excluded';
windowGrp.add(windowFrame);
// Eventuellement, une vitre
if (typeOuverture.includes('F1') || typeOuverture == 'F2' || typeOuverture == 'F2R' || typeOuverture == 'PF') {
var windowGlass = new THREE.Mesh(new THREE.BoxGeometry(largeur - 0.5, hauteur - 0.5, EPAISSEUR_MUR + 0.2), glassMaterial);
windowGlass.position.set(.5, .5, 0);
windowGlass.name = nomTravee + '>' + face + '>Ouverture ' + typeOuverture + '>Vitre';
windowGrp.add(windowGlass);
} else {
if (typeOuverture.includes('PG1')) {
var windowDoor = new THREE.Mesh(new THREE.BoxGeometry(largeur - 0.5, hauteur - 0.5, EPAISSEUR_MUR + 0.2), garageDoorMaterial);
} else if (typeOuverture.includes('PG2')) {
var windowDoor = new THREE.Mesh(new THREE.BoxGeometry(largeur - 0.5, hauteur - 0.5, EPAISSEUR_MUR + 0.2), garageDoorMaterial);
} else
var windowDoor = new THREE.Mesh(new THREE.BoxGeometry(largeur - 0.5, hauteur - 0.5, EPAISSEUR_MUR + 0.2), doorMaterial);
windowDoor.position.set(.5, .5, 0);
windowDoor.name = nomTravee + '>' + face + '>Ouverture ' + typeOuverture + '>Porte';
windowGrp.add(windowDoor);
}
}
windowGrp.name = nomTravee + '>' + face + '>Ouverture ' + typeOuverture;
objetsModifiables.push(windowGrp);
var positionX = 0,
positionY = 0,
positionZ = 0;
positionY = -(HAUTEUR_TRAVEE / 2) + (hauteur / 2) + elevation;
// On calcule la position en fonction du type d'ouverture, de la face de la travée et de la position de la travée.
// Pour rappel, l'ouverture est créée face à soi.
switch (face) {
case 'AV':
positionX = 0 + decalageX;
positionZ = (LONGUEUR_TRAVEE / 2) - epaisseur / 2 + 0.5;
break;
case 'AR':
windowGrp.rotation.y = Math.PI;
positionX = 0 - decalageX;
positionZ = -(LONGUEUR_TRAVEE / 2) + (epaisseur / 2) - 0.5;
break;
case 'PGAV':
windowGrp.rotation.y = -Math.PI / 2;
positionX = -(LARGEUR_TRAVEE / 2) + (epaisseur / 2) - 0.5;
positionZ = (LONGUEUR_TRAVEE / 4) + decalageX;
break;
case 'PGAR':
windowGrp.rotation.y = -Math.PI / 2;
positionX = -(LARGEUR_TRAVEE / 2) + (epaisseur / 2) - 0.5;
positionZ = -(LONGUEUR_TRAVEE / 4) + decalageX;
break;
case 'PDAV':
windowGrp.rotation.y = Math.PI / 2;
positionX = (LARGEUR_TRAVEE / 2) - (epaisseur / 2) + 0.5;
positionZ = (LONGUEUR_TRAVEE / 4) - decalageX;
break;
case 'PDAR':
windowGrp.rotation.y = Math.PI / 2;
positionX = (LARGEUR_TRAVEE / 2) - (epaisseur / 2) + 0.5;
positionZ = -(LONGUEUR_TRAVEE / 4) - decalageX;
break;
}
windowGrp.position.set(positionX, positionY, positionZ);
// Ne pas oublier de mettre à jour les scores VT de la travée !!!!!
switch (face) {
case 'AV':
if (tableauTravees[nomTravee]['nb_ouvertures_AV'] == 0) tableauTravees[nomTravee]['vt_AV'] = 0;
tableauTravees[nomTravee]['nb_ouvertures_AV']++;
tableauTravees[nomTravee]['vt_AV'] += PRODUITS[typeOuverture]['VT'];
break;
case 'AR':
if (tableauTravees[nomTravee]['nb_ouvertures_AR'] == 0) tableauTravees[nomTravee]['vt_AR'] = 0;
tableauTravees[nomTravee]['nb_ouvertures_AR']++;
tableauTravees[nomTravee]['vt_AR'] += PRODUITS[typeOuverture]['VT'];
break;
case 'PGAV':
if (tableauTravees[nomTravee]['nb_ouvertures_PGAV'] == 0) tableauTravees[nomTravee]['vt_PGAV'] = 0;
tableauTravees[nomTravee]['nb_ouvertures_PGAV']++;
tableauTravees[nomTravee]['vt_PGAV'] += PRODUITS[typeOuverture]['VT'];
break;
case 'PGAR':
if (tableauTravees[nomTravee]['nb_ouvertures_PGAR'] == 0) tableauTravees[nomTravee]['vt_PGAR'] = 0;
tableauTravees[nomTravee]['nb_ouvertures_PGAR']++;
tableauTravees[nomTravee]['vt_PGAR'] += PRODUITS[typeOuverture]['VT'];
break;
case 'PDAV':
if (tableauTravees[nomTravee]['nb_ouvertures_PDAV'] == 0) tableauTravees[nomTravee]['vt_PDAV'] = 0;
tableauTravees[nomTravee]['nb_ouvertures_PDAV']++;
tableauTravees[nomTravee]['vt_PDAV'] += PRODUITS[typeOuverture]['VT'];
break;
case 'PDAR':
if (tableauTravees[nomTravee]['nb_ouvertures_PDAR'] == 0) tableauTravees[nomTravee]['vt_PDAR'] = 0;
tableauTravees[nomTravee]['nb_ouvertures_PDAR']++;
tableauTravees[nomTravee]['vt_PDAR'] += PRODUITS[typeOuverture]['VT'];
break;
}
nbOuvertures++;
// Pour l'affichage en vue aérienne, on rajoute au sol la description du module, masquée par défaut.
var decalageIncrustationX = 0,
decalageIncrustationZ = 0;
var incrustation = createText(PRODUITS[typeOuverture]['codeModule'], taillePoliceIncrustations);
incrustation.rotation.x = -Math.PI / 2;
switch (face) {
case "AV":
decalageIncrustationZ = 10;
break;
case "AR":
decalageIncrustationZ = -10;
break;
case "PGAV":
decalageIncrustationX = -10;
break;
case "PDAV":
decalageIncrustationX = 10;
break;
case "PGAR":
decalageIncrustationX = -10;
break;
case "PDAR":
decalageIncrustationX = 10;
break;
}
incrustation.position.set(positionX + decalageIncrustationX, -(HAUTEUR_TRAVEE / 2), positionZ + decalageIncrustationZ);
incrustation.name = nomTravee + '>' + face + '>Incrustation';
modifierIncrustation(nomTravee, face, PRODUITS[typeOuverture]['codeModule']);
if (DEBUG) {
log('tableauTravee APRES creerOuverture :');
log(tableauTravees);
}
// On met à jour l'inventaire du projet.
inventaire[PRODUITS[typeOuverture]['codeModule']]++;
inventaire["MPL"]--;
return windowGrp;
}
export function creerComboOuvertures(nomTravee, nomFace, forcerIncrustation = false) {
var ouvertures = new Array();
var porte = creerOuverture(nomTravee, nomFace, 'PE', forcerIncrustation);
var fenetre = creerOuverture(nomTravee, nomFace, 'F1g', forcerIncrustation);
ouvertures.push(porte);
ouvertures.push(fenetre);
return ouvertures;
}
export function traitementCreationOuverture(nomTravee, nomFace, ouvertures) {
var nomOuverture;
if (Array.isArray(ouvertures)) nomOuverture = "PE+F1";
else nomOuverture = ouvertures.name;
// A la création d'une ouverture, on rajoute TOUJOURS dans la scene la texture "classique" d'abord...
if (nomOuverture != "PE+F1") { // Ouverture classique, hors combo "PE + F1"
scene.getObjectByName(nomTravee).add(ouvertures);
} else {
var porte = ouvertures[0];
var fenetre = ouvertures[1];
modifierIncrustation(nomTravee, nomFace, PRODUITS['PE+F1']['codeModule'])
inventaire["MF1"]--;
inventaire["MPE"]--;
inventaire["MPEF"]++;
inventaire["MPL"]++;
var nouveauGroupe = new THREE.Group();
nouveauGroupe = mergeGroups(porte, fenetre);
nouveauGroupe.name = nomTravee + '>' + nomFace + '>Ouverture ' + 'PE+F1';
objetsModifiables.push(nouveauGroupe);
tableauTravees[nomTravee]['nb_ouvertures_' + nomFace]--;
tableauTravees[nomTravee]['vt_' + nomFace] = PRODUITS['PE+F1']['VT'];
nbOuvertures--;
var laTravee = scene.getObjectByName(nomTravee);
laTravee.add(nouveauGroupe);
laTravee.remove(porte);
retirerObjetModifiable(porte.name);
laTravee.remove(fenetre);
retirerObjetModifiable(fenetre.name);
}
// .. et éventuellement, si l'on se trouve en mode "ossature bois", on masque l'ouverture avec sa
// texture "classique" et on affiche l'équivalent en ossature bois.
if ($("span:contains('ossatureBois')").parent().find("input[type='checkbox']").prop('checked')) {
if (nomOuverture != "PE+F1") {
var module = nomOuverture.substr(nomOuverture.lastIndexOf(' ') + 1, nomOuverture.length);
var mur = nomOuverture.substring(0, nomOuverture.lastIndexOf('>'));
var material;
if (module == 'PO') {
scene.getObjectByName(mur).material = MPI_Material;
} else {
scene.getObjectByName(nomOuverture).visible = false;
switch (module) {
case "PE":
material = MPE_Material;
break;
case "F1d":
material = MF1d_Material;
break;
case "F1g":
material = MF1g_Material;
break;
case "F2":
material = MF2_Material;
break;
case "PF":
material = MPF_Material;
break;
case "PG1":
material = MPG1_Material;
break;
case "PG2":
material = MPG2_Material;
break;
case "F2R":
material = MF2_Material;
break;
case "F1dR":
material = MF1d_Material;
break;
case "F1gR":
material = MF1g_Material;
break;
case "PER":
material = MPE_Material;
break;
}
scene.getObjectByName(mur).material = material;
}
} else {
// Combo PE + F1
scene.getObjectByName(nouveauGroupe.name).visible = false;
var mur = nouveauGroupe.name.substring(0, nouveauGroupe.name.lastIndexOf('>'));
var material = MPEF_Material;
scene.getObjectByName(mur).material = material;
}
}
}
export function creerToit(nomTravee) {
var prefixe = PREFIXE_TRAVEE + nbTravees;
var roofGrp = new THREE.Group();
var frontPan = new THREE.Mesh(new THREE.BoxBufferGeometry(LARGEUR_TRAVEE, (LONGUEUR_TRAVEE / 2) * 1.305, 0.2), roofMaterial);
frontPan.position.set(0, HAUTEUR_TRAVEE, (LONGUEUR_TRAVEE / 2) - 17.5);
frontPan.rotateX(-degrees_to_radians(55));
frontPan.castShadow = true;
frontPan.name = prefixe + '>toit_front_excluded';
roofGrp.add(frontPan);
var rearPan = frontPan.clone();
rearPan.rotateX(2 * degrees_to_radians(55));
rearPan.position.set(0, HAUTEUR_TRAVEE, -(LONGUEUR_TRAVEE / 2) + 17.5);
rearPan.castShadow = true;
rearPan.name = prefixe + '>toit_back_excluded';
roofGrp.add(rearPan);
var pignonGeometry = new THREE.Shape();
pignonGeometry.moveTo(-LONGUEUR_TRAVEE / 2, 0);
pignonGeometry.lineTo(0, (LONGUEUR_TRAVEE / 2) * 0.71, 0);
pignonGeometry.lineTo(LONGUEUR_TRAVEE / 2, 0, 0);
pignonGeometry.lineTo(0, 0);
var extrudeSettings = {
depth: EPAISSEUR_MUR,
bevelEnabled: false
};
var leftPignon = new THREE.Mesh(new THREE.ExtrudeGeometry(pignonGeometry, extrudeSettings), pignonMaterial);
leftPignon.geometry.faces[2].materialIndex = leftPignon.geometry.faces[3].materialIndex = 1;
leftPignon.rotation.y = Math.PI / 2;
leftPignon.position.set(-(LARGEUR_TRAVEE / 2), (HAUTEUR_TRAVEE / 2), 0);
leftPignon.name = prefixe + '>PEXT_gauche_excluded';
var rightPignon = new THREE.Mesh(new THREE.ExtrudeGeometry(pignonGeometry, extrudeSettings), pignonMaterial);
rightPignon.geometry.faces[2].materialIndex = rightPignon.geometry.faces[3].materialIndex = 1;
rightPignon.rotation.y = -Math.PI / 2;
rightPignon.position.set((LARGEUR_TRAVEE / 2), (HAUTEUR_TRAVEE / 2), 0);
rightPignon.name = prefixe + '>PEXT_droit_excluded';
roofGrp.add(leftPignon);
roofGrp.add(rightPignon);
roofGrp.name = nomTravee + '>Toit';
inventaire["SOLP"] += 1;
// Le reste de la MAJ de l'inventaire est traité dans la méthode appelante.
return roofGrp;
}
export function selectionnerSolivage(nomTravee, solivageChoisi) {
var plancher = scene.getObjectByName(nomTravee + ">plancher");
var ancienMaterial = plancher.material;
var ancienSolivage, familleSolivage, decalageIncrustation = 0;
if (ancienMaterial == SOLP_Material) ancienSolivage = "SOLP";
if (ancienMaterial == SOLT_Material) ancienSolivage = "SOLT";
if ((ancienMaterial == SOLE_1_Material) || (ancienMaterial == SOLE_2_Material)) ancienSolivage = "SOLE";
switch (solivageChoisi) {
case "SOLP":
familleSolivage = "SOLP";
plancher.material = SOLP_Material;
break;
case "SOLE_hg":
familleSolivage = "SOLE";
plancher.material = SOLE_1_Material;
plancher.rotation.z = 0;
break;
case "SOLE_hd":
familleSolivage = "SOLE";
plancher.material = SOLE_2_Material;
plancher.rotation.z = 0;
break;
case "SOLE_bd":
familleSolivage = "SOLE";
plancher.material = SOLE_1_Material;
plancher.rotation.z = Math.PI;
break;
case "SOLE_bg":
familleSolivage = "SOLE";
plancher.material = SOLE_2_Material;
plancher.rotation.z = Math.PI;
break;
case "SOLT_hc":
familleSolivage = "SOLT";
plancher.material = SOLT_Material;
plancher.rotation.z = 0;
break;
case "SOLT_bc":
familleSolivage = "SOLT";
plancher.material = SOLT_Material;
plancher.rotation.z = Math.PI;
break;
}
inventaire[ancienSolivage]--;
inventaire[familleSolivage]++;
if (ancienSolivage == "SOLP" && familleSolivage != "SOLP") nbOuvertures++;
tableauTravees[nomTravee].typeSolivage = solivageChoisi;
// Attention : coordonnées relatives et pas absolues
var positionIncrustation = 0;
if (solivageChoisi.indexOf("_h") != -1) positionIncrustation = -20;
if (solivageChoisi.indexOf("_b") != -1) positionIncrustation = 20;
scene.getObjectByName(nomTravee + ">plancher>Incrustation").position.z = positionIncrustation;
modifierIncrustation(nomTravee, "plancher", solivageChoisi);
}
export function gererDecalageTravee(laNouvelleTravee) {
if (nbTravees > 1) {
// Rajout d'une travée -> on décale tout le monde vers la gauche (suivant X).
laNouvelleTravee.translateX(LARGEUR_TRAVEE / 2 * (nbTravees - 1));
tableauTravees[laNouvelleTravee.name]['positionX'] += (LARGEUR_TRAVEE / 2 * (nbTravees - 1));
for (var i = nbTravees - 1; i > 0; i--) {
var traveePrecedente = scene.getObjectByName(PREFIXE_TRAVEE + i);
traveePrecedente.translateX(-LARGEUR_TRAVEE / 2);
tableauTravees[traveePrecedente.name]['positionX'] -= LARGEUR_TRAVEE / 2;
}
// La travée doit-elle être décalée suivant Z, car une nouvelle travée aura toujours le même décalage que sa voisine de gauche.
var decalageVoisineGauche = tableauTravees[PREFIXE_TRAVEE + (nbTravees - 1)]['decalage'];
if (decalageVoisineGauche != 0) {
switch (decalageVoisineGauche) {
case 1:
if (verifierPossibiliteDecalage(laNouvelleTravee.name, 'front')) {
decalerTravee(laNouvelleTravee.name, 'front', false);
}
break;
default:
if (verifierPossibiliteDecalage(laNouvelleTravee.name, 'back')) {
decalerTravee(laNouvelleTravee.name, 'back', false);
}
break;
}
}
// On masque les cloisons de la travée de gauche, ainsi que son pignon droit.
var voisineGauche = scene.getObjectByName(PREFIXE_TRAVEE + (nbTravees - 1));
voisineGauche.children[indicePDAV].visible = voisineGauche.children[indicePDAR].visible = false;
voisineGauche.children[indiceToit].children[indicePignonDroit].visible = false;
// Le pignon séparant les 2 travées devient un pignon intérieur, donc sélectionnable.
laNouvelleTravee.children[indiceToit].children[indicePignonGauche].name = laNouvelleTravee.name + ">PINT";
laNouvelleTravee.children[indiceToit].children[indicePignonGauche].material = PINT_Droite_Material;
// Enfin, on re-crée une ouverture dans la travée la plus à gauche.
selectionnerSolivage('Travee 1', "SOLT_bc");
}
}
export function verifierPossibiliteDecalage(nomTravee, direction, modeVerbose = true) {
// Avant de décaler une travée, on vérifier les conditions sont remplies.
if (nbTravees <= 1) {
if (modeVerbose) {
alerte("Vous devez avoir plus d'une travée dans votre projet.");
}
return false;
}
if ((direction == 'front' && tableauTravees[nomTravee]['decalage'] == 1) ||
(direction == 'back' && tableauTravees[nomTravee]['decalage'] == -1)) {
if (modeVerbose) {
alerte("Travée déjà décalée dans cette direction.");
}
return false;
}
return true;
}
export function decalerTravee(nomTravee, direction, modeVerbose = true) {
/*
if (modeVerbose) {
if (nbOuvertures > 0) {
if (modeVerbose) {
if (!confirm("Vous allez perdre toutes les ouvertures déjà créées. Continuer ?")) return;
}
unSelect();
supprimerToutesOuvertures();
if ($("span:contains('ossatureBois')").parent().find("input[type='checkbox']").prop('checked'))
$("span:contains('ossatureBois')").click();
}
}
*/
var travee = scene.getObjectByName(nomTravee);
var numTravee = parseInt(nomTravee.substr(nomTravee.indexOf(' ') + 1, 2));
var nomTraveeGauche = nomTravee.substr(0, nomTravee.indexOf(' ') + 1) + (numTravee - 1);
var nomTraveeDroite = nomTravee.substr(0, nomTravee.indexOf(' ') + 1) + (numTravee + 1);
var traveeGauche = scene.getObjectByName(nomTraveeGauche);
var traveeDroite = scene.getObjectByName(nomTraveeDroite);
// Si ce décalage déclenche la création d'une 3° construction, alors stop.
// On simule le recalcul des constructions...
var tableauDecalages = [];
for (var item in tableauTravees) {
if (tableauTravees.hasOwnProperty(item)) {
var laTravee = tableauTravees[item];
tableauDecalages.push(laTravee['decalage']);
}
}
if (direction == 'front') { // décalage vers l'avant
tableauDecalages[numTravee - 1] += 1;
var resultatsSimulation = simulerCalculConstructions(tableauDecalages);
var nbConstructionSimule = resultatsSimulation[0];
if (nbConstructionSimule > NB_CONSTRUCTIONS_MAXI) {
if (modeVerbose) {
alerte("Décalage refusé : nombre maximum de constructions atteint (" + NB_CONSTRUCTIONS_MAXI + ").");
}
return;
}
if ((resultatsSimulation[1] > NB_TRAVEES_MAXI) || (resultatsSimulation[2] > NB_TRAVEES_MAXI)) {
if (modeVerbose) {
alerte("Décalage refusé : nombre maximum de travées atteint (" + NB_TRAVEES_MAXI + ").");
}
return;
}
if (modeVerbose) {
if (nbOuvertures > 0) {
if (!confirm("Vous allez perdre toutes les ouvertures déjà créées. Continuer ?")) return;
unSelect();
supprimerToutesOuvertures();
if ($("span:contains('ossatureBois')").parent().find("input[type='checkbox']").prop('checked'))
$("span:contains('ossatureBois')").click();
}
}
// On masque certains murs de la travée courante et également des travées adjacentes.
if (traveeDroite) {
var decalageTraveeDroite = tableauTravees[nomTraveeDroite]['decalage'];
if (Math.abs(decalageTraveeDroite - (tableauTravees[nomTravee]['decalage'] + 1)) > 1) {
if (modeVerbose) {
alerte("Impossible de réaliser un tel décalage.");
}
return;
} else {
// On teste la position du décalage entre travées AVANT le décalage.
if (decalageTraveeDroite == tableauTravees[nomTravee]['decalage']) {
// Cas A
travee.children[indicePDAV].visible = travee.children[indicePDAR].visible = true;
traveeDroite.children[indicePGAV].visible = traveeDroite.children[indicePGAR].visible = true;
// Gestion des pignons (changement de nom + de texture)
travee.children[indiceToit].children[indicePignonDroit].visible = true;
travee.children[indiceToit].children[indicePignonDroit].name = "PEXT_droit_excluded";
travee.children[indiceToit].children[indicePignonDroit].material = pignonMaterial;
modifierIncrustation(travee.name, "PD", "PEXT");
traveeDroite.children[indiceToit].children[indicePignonGauche].name = "PEXT_gauche_excluded";
traveeDroite.children[indiceToit].children[indicePignonGauche].material = pignonMaterial;
modifierIncrustation(traveeDroite.name, "PG", "PEXT");
inventaire["MPL"] += 2;
modifierIncrustation(travee.name, "PDAR", "MPL");
} else {
// Cas B
travee.children[indicePDAV].visible = travee.children[indicePDAR].visible = false;
traveeDroite.children[indicePGAV].visible = traveeDroite.children[indicePGAR].visible = true;
// Gestion des pignons (changement de nom + de texture)
travee.children[indiceToit].children[indicePignonDroit].visible = false;
modifierIncrustation(travee.name, "PD", "PINT");
traveeDroite.children[indiceToit].children[indicePignonGauche].name = traveeDroite.name + ">PINT";
traveeDroite.children[indiceToit].children[indicePignonGauche].material = PINT_Droite_Material;
modifierIncrustation(traveeDroite.name, "PG", "PINT");
inventaire["MPL"] -= 2;
}
}
}
if (traveeGauche) {
var decalageTraveeGauche = tableauTravees[nomTraveeGauche]['decalage'];
if (Math.abs(decalageTraveeGauche - (tableauTravees[nomTravee]['decalage'] + 1)) > 1) {
if (modeVerbose) {
alerte("Impossible de réaliser un tel décalage.");
}
return;
} else {
// On teste la position du décalage entre travées AVANT le décalage.
if (decalageTraveeGauche == tableauTravees[nomTravee]['decalage']) {
// Cas C
travee.children[indicePGAV].visible = travee.children[indicePGAR].visible = true;
traveeGauche.children[indicePDAR].visible = traveeGauche.children[indicePDAV].visible = true;
// Gestion des pignons (changement de nom + de texture)
traveeGauche.children[indiceToit].children[indicePignonDroit].visible = true;
travee.children[indiceToit].children[indicePignonGauche].name = "PEXT_gauche_excluded";
travee.children[indiceToit].children[indicePignonGauche].material = pignonMaterial;
modifierIncrustation(travee.name, "PG", "PEXT");
traveeGauche.children[indiceToit].children[indicePignonDroit].name = "PEXT_droit_excluded";
traveeGauche.children[indiceToit].children[indicePignonDroit].material = pignonMaterial;
modifierIncrustation(traveeGauche.name, "PD", "PEXT");
inventaire["MPL"] += 2;
modifierIncrustation(traveeGauche.name, "PDAR", "MPL");
} else {
// Cas D
travee.children[indicePGAV].visible = travee.children[indicePGAR].visible = true;
traveeGauche.children[indicePDAV].visible = traveeGauche.children[indicePDAR].visible = false;
// Gestion des pignons (changement de nom + de texture)
traveeGauche.children[indiceToit].children[indicePignonDroit].visible = false;
modifierIncrustation(traveeGauche.name, "PD", "PINT");
travee.children[indiceToit].children[indicePignonGauche].name = nomTravee + ">PINT";
travee.children[indiceToit].children[indicePignonGauche].material = PINT_Droite_Material;
modifierIncrustation(travee.name, "PG", "PINT");
inventaire["MPL"] -= 2;
}
}
}
travee.position.z += (LONGUEUR_TRAVEE / 2);
tableauTravees[nomTravee]['positionZ'] += (LONGUEUR_TRAVEE / 2);
tableauTravees[nomTravee]['decalage']++;
} else { // décalage vers le fond
tableauDecalages[numTravee - 1] -= 1;
var resultatsSimulation = simulerCalculConstructions(tableauDecalages);
var nbConstructionSimule = resultatsSimulation[0];
if (nbConstructionSimule > NB_CONSTRUCTIONS_MAXI) {
if (modeVerbose) {
alerte("Décalage refusé : nombre maximum de constructions atteint (" + NB_CONSTRUCTIONS_MAXI + ").");
}
return;
}
if ((resultatsSimulation[1] > NB_TRAVEES_MAXI) || (resultatsSimulation[2] > NB_TRAVEES_MAXI)) {
if (modeVerbose) {
alerte("Décalage refusé : nombre maximum de travées atteint (" + NB_TRAVEES_MAXI + ").");
}
return;
}
if (modeVerbose) {
if (nbOuvertures > 0) {
if (!confirm("Vous allez perdre toutes les ouvertures déjà créées. Continuer ?")) return;
unSelect();
supprimerToutesOuvertures();
if ($("span:contains('ossatureBois')").parent().find("input[type='checkbox']").prop('checked'))
$("span:contains('ossatureBois')").click();
}
}
// On masque certains murs de la travée courante et également des travées adjacentes.
if (traveeDroite) {
var decalageTraveeDroite = tableauTravees[nomTraveeDroite]['decalage'];
if (Math.abs(decalageTraveeDroite - (tableauTravees[nomTravee]['decalage'] - 1)) > 1) {
if (modeVerbose) {
alerte("Impossible de réaliser un tel décalage.");
}
return;
} else {
// On teste la position du décalage entre travées AVANT le décalage.
if (decalageTraveeDroite == tableauTravees[nomTravee]['decalage']) {
// Cas E
travee.children[indicePDAR].visible = travee.children[indicePDAV].visible = true;
traveeDroite.children[indicePGAR].visible = traveeDroite.children[indicePGAV].visible = true;
// Gestion des pignons (changement de nom + de texture)
travee.children[indiceToit].children[indicePignonDroit].visible = true;
travee.children[indiceToit].children[indicePignonDroit].name = "PEXT_droit_excluded";
travee.children[indiceToit].children[indicePignonDroit].material = pignonMaterial;
modifierIncrustation(travee.name, "PD", "PEXT");
traveeDroite.children[indiceToit].children[indicePignonGauche].name = "PEXT_gauche_excluded";
traveeDroite.children[indiceToit].children[indicePignonGauche].material = pignonMaterial;
modifierIncrustation(traveeDroite.name, "PG", "PEXT");
inventaire["MPL"] += 2;
} else {
// Cas F
travee.children[indicePDAV].visible = travee.children[indicePDAR].visible = false;
traveeDroite.children[indicePGAV].visible = traveeDroite.children[indicePGAR].visible = true;
travee.children[indiceToit].children[indicePignonDroit].visible = false;
modifierIncrustation(travee.name, "PD", "PINT");
// Gestion des pignons (changement de nom + de texture)
traveeDroite.children[indiceToit].children[indicePignonGauche].name = traveeDroite.name + ">PINT";
traveeDroite.children[indiceToit].children[indicePignonGauche].material = PINT_Droite_Material;
modifierIncrustation(traveeDroite.name, "PG", "PINT");
inventaire["MPL"] -= 2;
}
}
}
if (traveeGauche) {
var decalageTraveeGauche = tableauTravees[nomTraveeGauche]['decalage'];
if (Math.abs(decalageTraveeGauche - (tableauTravees[nomTravee]['decalage'] - 1)) > 1) {
if (modeVerbose) {
alerte("Impossible de réaliser un tel décalage.");
}
return;
} else {
// On teste la position du décalage entre travées AVANT le décalage.
if (decalageTraveeGauche == tableauTravees[nomTravee]['decalage']) {
// Cas G
travee.children[indicePGAV].visible = travee.children[indicePGAR].visible = true;
traveeGauche.children[indicePDAV].visible = traveeGauche.children[indicePDAR].visible = true;
// Gestion des pignons (changement de nom + de texture)
traveeGauche.children[indiceToit].children[indicePignonDroit].visible = true;
travee.children[indiceToit].children[indicePignonGauche].name = "PEXT_gauche_excluded";
travee.children[indiceToit].children[indicePignonGauche].material = pignonMaterial;
modifierIncrustation(travee.name, "PG", "PEXT");
traveeGauche.children[indiceToit].children[indicePignonDroit].name = "PEXT_droit_excluded";
traveeGauche.children[indiceToit].children[indicePignonDroit].material = pignonMaterial;
modifierIncrustation(traveeGauche.name, "PD", "PEXT");
inventaire["MPL"] += 2;
} else {
// Cas H
travee.children[indicePGAV].visible = travee.children[indicePGAR].visible = true;
traveeGauche.children[indicePDAV].visible = traveeGauche.children[indicePDAR].visible = false;
// Gestion des pignons (changement de nom + de texture)
traveeGauche.children[indiceToit].children[indicePignonDroit].visible = false;
modifierIncrustation(traveeGauche.name, "PD", "PINT");
travee.children[indiceToit].children[indicePignonGauche].name = nomTravee + ">PINT";
travee.children[indiceToit].children[indicePignonGauche].material = PINT_Droite_Material;
modifierIncrustation(travee.name, "PG", "PINT");
inventaire["MPL"] -= 2;
}
}
}
travee.position.z -= (LONGUEUR_TRAVEE / 2);
tableauTravees[nomTravee]['positionZ'] -= (LONGUEUR_TRAVEE / 2);
tableauTravees[nomTravee]['decalage']--;
}
recalculerConstructions();
recreerTrappes();
incrusterCotes();
unSelect();
}
export function creerTravee(modeVerbose = true) {
var prefixe = PREFIXE_TRAVEE + (nbTravees + 1);
tableauTravees[prefixe] = new Array();
// On teste d'abord si la construction de la nouvelle travée est autorisée : si ce n'est pas le cas, inutile d'aller plus loin.
recalculerConstructions();
if (nbTravees == (NB_TRAVEES_MAXI * NB_CONSTRUCTIONS_MAXI)) {
if (modeVerbose) {
var message = "Vous avez atteint le nombre maximal de travées autorisées (" + NB_TRAVEES_MAXI + " travées pour " + NB_CONSTRUCTIONS_MAXI + " constructions).";
alerte(message);
}
return;
}
nbTravees++;
// Un module = 6 murs (AV + AR + 2 par pignon) + un sol + un plafond
// IMPORTANT : on crée les murs avec la face extérieure DEVANT !!!!!!!!!!
var wallAR = new THREE.Mesh(new THREE.BoxGeometry(LARGEUR_TRAVEE, HAUTEUR_TRAVEE, EPAISSEUR_MUR), wallMaterial);
wallAR.position.z = -(LONGUEUR_TRAVEE / 2) + (EPAISSEUR_MUR / 2);
var wallPDAR = new THREE.Mesh(new THREE.BoxGeometry(LONGUEUR_TRAVEE / 2 - EPAISSEUR_MUR, HAUTEUR_TRAVEE, EPAISSEUR_MUR), wallMaterial);
wallPDAR.rotation.y = -Math.PI / 2;
wallPDAR.position.x = ((-EPAISSEUR_MUR / 2) + LARGEUR_TRAVEE / 2) - 0.01;
wallPDAR.position.z = -(LONGUEUR_TRAVEE / 4) + EPAISSEUR_MUR / 2;
var wallPDAV = new THREE.Mesh(new THREE.BoxGeometry(LONGUEUR_TRAVEE / 2 - EPAISSEUR_MUR, HAUTEUR_TRAVEE, EPAISSEUR_MUR), wallMaterial);
wallPDAV.rotation.y = -Math.PI / 2;
wallPDAV.position.x = (-EPAISSEUR_MUR / 2) + LARGEUR_TRAVEE / 2;
wallPDAV.position.z = (LONGUEUR_TRAVEE / 4) - EPAISSEUR_MUR / 2;
var wallAV = new THREE.Mesh(new THREE.BoxGeometry(LARGEUR_TRAVEE, HAUTEUR_TRAVEE, EPAISSEUR_MUR), wallMaterial);
wallAV.rotation.y = Math.PI;
wallAV.position.z = (LONGUEUR_TRAVEE / 2) - (EPAISSEUR_MUR / 2);
var wallPGAV = new THREE.Mesh(new THREE.BoxGeometry(LONGUEUR_TRAVEE / 2 - EPAISSEUR_MUR, HAUTEUR_TRAVEE, EPAISSEUR_MUR), wallMaterial);
wallPGAV.rotation.y = Math.PI / 2;
wallPGAV.position.x = (EPAISSEUR_MUR / 2) - LARGEUR_TRAVEE / 2;
wallPGAV.position.z = (LONGUEUR_TRAVEE / 4) - EPAISSEUR_MUR / 2;
var wallPGAR = new THREE.Mesh(new THREE.BoxGeometry(LONGUEUR_TRAVEE / 2 - EPAISSEUR_MUR, HAUTEUR_TRAVEE, EPAISSEUR_MUR), wallMaterial);
wallPGAR.rotation.y = Math.PI / 2;
wallPGAR.position.x = (EPAISSEUR_MUR / 2) - LARGEUR_TRAVEE / 2;
wallPGAR.position.z = -(LONGUEUR_TRAVEE / 4) + EPAISSEUR_MUR / 2;
var floor = new THREE.Mesh(new THREE.PlaneBufferGeometry(LARGEUR_TRAVEE, LONGUEUR_TRAVEE), floorMaterial);
floor.position.set(0, (-HAUTEUR_TRAVEE / 2) + .01, 0);
floor.rotation.x = -Math.PI / 2;
floor.name = 'floor_excluded';
var topGeometry = new THREE.BoxGeometry(LARGEUR_TRAVEE - 0.2, LONGUEUR_TRAVEE - 0.2, 0.2);
var top = new THREE.Mesh(topGeometry, SOLP_Material);
top.rotation.x = -Math.PI / 2;
top.position.set(0, (HAUTEUR_TRAVEE / 2) + .01, 0);
top.visible = true;
top.name = prefixe + '>plancher';
var wallsGrp = new THREE.Group();
wallsGrp.add(wallAR);
wallAR.name = prefixe + '>AR';
wallsGrp.add(wallPDAR);
wallPDAR.name = prefixe + '>PDAR';
wallsGrp.add(wallPDAV);
wallPDAV.name = prefixe + '>PDAV';
wallsGrp.add(wallAV);
wallAV.name = prefixe + '>AV';
wallsGrp.add(wallPGAV);
wallPGAV.name = prefixe + '>PGAV';
wallsGrp.add(wallPGAR);
wallPGAR.name = prefixe + '>PGAR';
wallsGrp.add(floor);
wallsGrp.add(top);
wallsGrp.name = prefixe;
objetsModifiables.push(wallsGrp);
// Pour la gestion des ombres
for (var i = 0; i < wallsGrp.children.length; i++) {
wallsGrp.children[i].receiveShadow = false;
wallsGrp.children[i].castShadow = true;
}
var toit = creerToit(prefixe);
wallsGrp.add(toit);
// Initialisation de tableauTravees (qui contient les infos utilisées pour calculer le score VT notamment)
tableauTravees.length++;
tableauTravees[prefixe]['nom'] = prefixe;
tableauTravees[prefixe]['nb_ouvertures_AR'] = 0;
tableauTravees[prefixe]['nb_ouvertures_PDAR'] = 0;
tableauTravees[prefixe]['nb_ouvertures_PDAV'] = 0;
tableauTravees[prefixe]['nb_ouvertures_AV'] = 0;
tableauTravees[prefixe]['nb_ouvertures_PGAV'] = 0;
tableauTravees[prefixe]['nb_ouvertures_PGAR'] = 0;
tableauTravees[prefixe]['decalage'] = 0;
tableauTravees[prefixe]['positionX'] = 0;
tableauTravees[prefixe]['positionZ'] = 0;
// Détermination du numéro de construction et du rang de la travée courante
if (nbTravees == 1) {
tableauTravees[prefixe]['numConstruction'] = 1;
tableauTravees[prefixe]['rangDansConstruction'] = 1;
} else {
var constructionVoisine = tableauTravees[PREFIXE_TRAVEE + (nbTravees - 1)]['numConstruction'];
var rangVoisine = tableauTravees[PREFIXE_TRAVEE + (nbTravees - 1)]['rangDansConstruction'];
if (rangVoisine == NB_TRAVEES_MAXI) {
nbConstructions++;
tableauTravees[prefixe]['numConstruction'] = nbConstructions;
tableauTravees[prefixe]['rangDansConstruction'] = 1;
} else {
tableauTravees[prefixe]['numConstruction'] = constructionVoisine;
tableauTravees[prefixe]['rangDansConstruction'] = rangVoisine + 1;
}
}
// Gestion de l'incrustation pour la vue d'implantation
var lesMurs = new Array('AV', 'AR', 'PGAV', 'PGAR', 'PDAR', 'PDAV');
var DECALAGE_INCRUSTATION = 7;
for (var i = 0; i < 6; i++) {
var decalageIncrustationX = 0,
decalageIncrustationZ = 0;
var incrustation = createText(PRODUITS['MU']['codeModule'], taillePoliceIncrustations);
incrustation.rotation.x = -Math.PI / 2;
var positionX = 0;
var positionZ = 0;
switch (lesMurs[i]) {
case "AV":
positionX = wallAV.position.x;
positionZ = wallAV.position.z;
decalageIncrustationZ = -DECALAGE_INCRUSTATION;
break;
case "AR":
positionX = wallAR.position.x;
positionZ = wallAR.position.z;
decalageIncrustationZ = +DECALAGE_INCRUSTATION;
break;
case "PGAV":
positionX = wallPGAV.position.x;
positionZ = wallPGAV.position.z;
decalageIncrustationX = DECALAGE_INCRUSTATION;
break;
case "PDAV":
positionX = wallPDAV.position.x;
positionZ = wallPDAV.position.z;
decalageIncrustationX = -DECALAGE_INCRUSTATION;
break;
case "PGAR":
positionX = wallPGAR.position.x;
positionZ = wallPGAR.position.z;
decalageIncrustationX = DECALAGE_INCRUSTATION;
break;
case "PDAR":
positionX = wallPDAR.position.x;
positionZ = wallPDAR.position.z;
decalageIncrustationX = -DECALAGE_INCRUSTATION;
break;
}
incrustation.position.set(positionX + decalageIncrustationX, -(HAUTEUR_TRAVEE / 2), positionZ + decalageIncrustationZ);
incrustation.name = prefixe + ">" + lesMurs[i] + ">Incrustation";
incrustation.visible = false;
wallsGrp.add(incrustation);
}
// Incrustation pour les pignons de toiture et le solivage
var positionX, positionY, positionZ = 0;
var incrustation = createText('PEXT', taillePoliceIncrustations);
incrustation.rotation.x = -Math.PI / 2;
positionX = -(LARGEUR_TRAVEE / 2) + 6;
positionY = (HAUTEUR_TRAVEE / 2) + 0.1;
incrustation.position.set(positionX, positionY, positionZ);
incrustation.name = prefixe + '>PG>Incrustation';
wallsGrp.add(incrustation);
var incrustation = createText('PEXT', taillePoliceIncrustations);
incrustation.rotation.x = -Math.PI / 2;
positionX = (LARGEUR_TRAVEE / 2) - 6;
incrustation.position.set(positionX, positionY, positionZ);
incrustation.name = prefixe + '>PD>Incrustation';
wallsGrp.add(incrustation);
var incrustation = createText('SOLP', taillePoliceIncrustations);
incrustation.rotation.x = -Math.PI / 2;
incrustation.position.set(0, positionY, 0);
incrustation.name = prefixe + '>plancher>Incrustation';
wallsGrp.add(incrustation);
tableauTravees[prefixe].typeSolivage = "SOLP";
hidePignonIncrustations();
initialiserScoresVT(PREFIXE_TRAVEE + nbTravees);
inventaire["MPL"] += 6;
if (DEBUG) {
log('tableauTravees dans creerTravee : ');
log(tableauTravees);
}
return wallsGrp;
}
export function traitementCreationTravee(travee) {
scene.add(travee);
gererDecalageTravee(travee);
// On modifie l'incrustation pour les pignons de toiture.
if (nbTravees > 1) {
modifierIncrustation(travee.name, 'PG', 'PINT', true);
var voisine = scene.getObjectByName(PREFIXE_TRAVEE + (nbTravees - 1));
modifierIncrustation(voisine.name, 'PD', 'PINT', true);
inventaire["MPL"] -= 2; // Car 2 murs disparaissent.
}
hidePignonIncrustations();
recalculerConstructions();
incrusterCotes();
// On déplace également la boussole pour qu'elle soit toujours à la même distance de la droite de la construction
scene.getObjectByName('boussole').position.x = tableauTravees["Travee " + nbTravees].positionX + 40;
restaurerPrefsUtilisateur(nbTravees, travee);
}