1182 lines
49 KiB
JavaScript
Executable File
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);
|
|
}
|