First commit

This commit is contained in:
2024-01-18 15:18:18 +01:00
commit d87b7c251e
120 changed files with 34736 additions and 0 deletions

1180
js/OrbitControls.js Executable file

File diff suppressed because it is too large Load Diff

13
js/dat.gui.min.js vendored Executable file

File diff suppressed because one or more lines are too long

134
js/environment.js Executable file
View File

@@ -0,0 +1,134 @@
import {
COLOR_ARRAY,
groundMaterial,
boussoleMaterial
} from "./materials.js"
// Renderer
export var renderer = new THREE.WebGLRenderer({
antialias: true,
preserveDrawingBuffer: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.gammaFactor = 2.2;
export var aspectRatio = window.innerWidth / window.innerHeight;
var frustumSize = 300;
// Camera
export var camera = new THREE.PerspectiveCamera(50, aspectRatio, 1, 1000);
initPositionCamera(camera);
export var cameraOrtho = new THREE.OrthographicCamera(frustumSize * aspectRatio / -2, frustumSize * aspectRatio / 2, frustumSize / 2, frustumSize / -2, 1, 500);
initPositionCamera(cameraOrtho);
// Environnement
var ground = new THREE.Mesh(new THREE.PlaneBufferGeometry(1200, 1200), groundMaterial);
ground.position.y = -12.5;
ground.rotation.x = -Math.PI / 2;
ground.receiveShadow = true;
ground.castShadow = false;
ground.matrixAutoUpdate = false;
ground.updateMatrix();
ground.name = 'ground';
scene.add(ground)
scene.background = COLOR_ARRAY['bleu_ciel'];
scene.fog = new THREE.Fog(COLOR_ARRAY['blanc'], 300, 2000);
/********************* SkyBox ******************/
var path = "/img/skybox/";
var format = '.png';
var imgArray = [
path + 'front' + format,
path + 'back' + format,
path + 'top' + format,
path + 'bottom' + format,
path + 'right' + format,
path + 'left' + format
];
var textureCube = new THREE.CubeTextureLoader().load(imgArray);
textureCube.encoding = THREE.sRGBEncoding;
scene.background = textureCube;
/*****************************************************/
// Repère face avant
var boussole = new THREE.Mesh(new THREE.PlaneBufferGeometry(12, 12), boussoleMaterial);
boussole.name = 'boussole';
boussole.rotation.x = -Math.PI / 2;
boussole.position.set(50, -(HAUTEUR_TRAVEE / 2) + 0.1, 0);
scene.add(boussole);
// Eclairage
var ambient = new THREE.AmbientLight(COLOR_ARRAY['jaune'], 0.45);
ambient.name = "ambientLight";
scene.add(ambient);
const reference = 200;
// Une lampe derrière pour l'ombre des bâtiments
export var rearLight = new THREE.DirectionalLight(COLOR_ARRAY['blanc'], 0.6);
rearLight.position.set(reference, reference, -reference / 2);
rearLight.castShadow = true;
rearLight.shadow.mapSize.width = reference;
rearLight.shadow.mapSize.height = reference;
rearLight.shadow.camera.left = rearLight.shadow.camera.bottom = -reference;
rearLight.shadow.camera.right = rearLight.shadow.camera.top = reference;
rearLight.shadow.camera.near = 1;
rearLight.shadow.camera.far = reference * 2;
rearLight.name = "rearLight";
scene.add(rearLight);
// Une lampe devant pour éclairer la façade
export var frontLight = new THREE.SpotLight(COLOR_ARRAY['blanc'], 0.2);
frontLight.position.set(10, HAUTEUR_TRAVEE, 300);
frontLight.castShadow = false;
frontLight.name = "frontLight";
scene.add(frontLight);
export var leftLight = new THREE.SpotLight(COLOR_ARRAY['blanc'], 0.1);
leftLight.position.set(-300, HAUTEUR_TRAVEE, 0);
leftLight.castShadow = false;
leftLight.name = "leftLight";
scene.add(leftLight);
export var rightLight = new THREE.SpotLight(COLOR_ARRAY['blanc'], 0.05);
rightLight.position.set(300, HAUTEUR_TRAVEE, 0);
rightLight.castShadow = false;
rightLight.name = "righLight";
scene.add(rightLight);
export function initPositionCamera(cameraActuelle) {
if (cameraActuelle == cameraOrtho) {
cameraOrtho.position.set(0, 200, 0);
cameraOrtho.left = -100;
cameraOrtho.right = 100;
cameraOrtho.top = ((cameraOrtho.right - cameraOrtho.left) / aspectRatio) / 2;
cameraOrtho.bottom = -((cameraOrtho.right - cameraOrtho.left) / aspectRatio) / 2;
cameraOrtho.near = 1;
cameraOrtho.far = 300;
camera.aspect = aspectRatio;
cameraOrtho.lookAt(scene.position);
} else {
camera.position.set(60, 40, 160);
camera.aspect = aspectRatio;
camera.fov = 50;
camera.lookAt(scene.position);
}
}
document.body.appendChild(renderer.domElement);
export var canvas = renderer.domElement;

545
js/events.js Executable file
View File

@@ -0,0 +1,545 @@
import {
camera,
cameraOrtho,
renderer,
aspectRatio
} from "./environment.js"
import {
COLOR_ARRAY,
windowMaterial,
glassMaterial,
selectedGlassMaterial,
doorMaterial,
selectedDoorMaterial,
SOLP_Material,
SOLE_1_Material,
SOLE_2_Material,
SOLT_Material,
MPE_Material,
MF1d_Material,
MF1g_Material,
MF2_Material,
MPEF_Material,
MPF_Material,
MPI_Material,
MPG1_Material,
MPG2_Material,
PINT_Gauche_Material,
PINT_Droite_Material,
PEXT_Material,
createText
}
from "./materials.js"
import {
info,
alerte,
log,
extraireNomTravee,
extraireFace,
verifierContraintes,
mergeGroups,
retirerObjetModifiable,
faceInterieureOuExterieure,
modifierIncrustation,
showMainIncrustations,
hideMainIncrustations,
showPignonIncrustations,
hidePignonIncrustations,
animate,
traduireNomObjet,
calculerTaillePoliceOptimale,
redimensionnerIncrustations,
rechercherFaceOpposee,
verifierControlesMetier
} from "./main.js"
import {
displayContextualMenu,
displayOpenings,
displayPignonOpenings,
chooseFloorHole,
unSelect,
changePointOfView,
afficherVueAerienne
} from "./gui.js"
import {
supprimerOuverture,
decalerTravee,
creerTravee,
creerOuverture,
creerComboOuvertures,
supprimerToutesOuvertures,
traitementCreationTravee,
traitementCreationOuverture,
selectionnerSolivage,
verifierPossibiliteDecalage,
recreerTrappes
} from "./objects.js"
/******************************* Gestion du clic sur le menu déroulant **************************************/
$(".liste-deroulante").click(function (e) {
e.preventDefault();
var action = $(e.target).attr('data-action');
var autorise = $(e.target).attr('class');
if (autorise && autorise.indexOf('disabled') > -1) {
var message = "Opération non autorisée : ";
if (action == 'addOpening') message += "une ouverture est déjà présente sur ce mur.";
if (action.startsWith('move')) message += "décalage impossible dans cette configuration.";
alerte(message);
return;
}
switch (action) {
case 'deleteOuverture':
var backupObjetSelectionne = objetSelectionne;
var typeOuverture = objetSelectionne.substring(objetSelectionne.indexOf("Ouverture"), objetSelectionne.lastIndexOf('>'));
supprimerOuverture(scene.getObjectByName(objetSelectionne).parent.name);
// Pour les cas de modules en jonction, il faut également supprimer l'ouverture qui est en face.
var faceOpposee = rechercherFaceOpposee(extraireNomTravee(backupObjetSelectionne), extraireFace(backupObjetSelectionne));
if (faceOpposee != null) {
var autreOuverture = faceOpposee[0] + ">" + faceOpposee[1] + ">" + typeOuverture;
supprimerOuverture(autreOuverture);
}
break;
case 'addOpening':
displayOpenings(objetSelectionne, faceInterieureOuExterieure(objetSelectionne));
break;
case 'moveFrontTravee':
var nomTravee = extraireNomTravee(objetSelectionne);
if (verifierPossibiliteDecalage(nomTravee, 'front')) {
decalerTravee(nomTravee, 'front');
}
break;
case 'moveBackTravee':
var nomTravee = extraireNomTravee(objetSelectionne);
if (verifierPossibiliteDecalage(nomTravee, 'back')) {
decalerTravee(nomTravee, 'back');
}
break;
case 'chooseFloorHole':
chooseFloorHole(extraireNomTravee(objetSelectionne));
break;
case 'unselect':
unSelect();
break;
case 'addPignonOpening':
displayPignonOpenings(objetSelectionne);
break;
default:
alert('Autre action inconnue !');
break;
}
$("#div-menu-contextuel").hide();
});
/******************************* Gestion des clics dans la popup des pignons *********************************/
$("#popup-pignon").click(function (e) {
e.stopImmediatePropagation();
if ($(e.target).attr('id') == 'popup-alerte-annuler') {
$(".popup-ouverture").hide();
$("#overlay").hide();
unSelect();
return;
}
var laTravee = extraireNomTravee(objetSelectionne);
var pignonSelectionne = scene.getObjectByName(objetSelectionne);
switch ($(e.target).parent().attr('id')) {
case "gauche":
pignonSelectionne.material = PINT_Gauche_Material;
tableauTravees[laTravee].typePINT = "gauche";
break;
case "droite":
pignonSelectionne.material = PINT_Droite_Material;
tableauTravees[laTravee].typePINT = "droite";
break;
}
$(".popup-ouverture").hide();
$("#overlay").hide();
unSelect();
});
/******************************* Gestion des clics dans la popup des planchers *********************************/
$("#popup-plancher").click(function (e) {
e.stopImmediatePropagation();
if ($(e.target).attr('id') == 'popup-alerte-annuler') {
$(".popup-ouverture").hide();
$("#overlay").hide();
unSelect();
return;
}
if (!$(e.target).parent().hasClass('disabled')) {
var nomTravee = extraireNomTravee(objetSelectionne);
var nomFace = extraireFace(objetSelectionne);
var solivageChoisi = $(e.target).parent().attr('id');
if (verifierControlesMetier(solivageChoisi, tableauTravees[nomTravee].numConstruction)) {
var typeSolivage, decalageIncrustation = 0;
selectionnerSolivage(nomTravee, solivageChoisi);
$(".popup-ouverture").hide();
$("#overlay").hide();
unSelect();
} else {
unSelect();
$("#overlay").hide();
$(".popup-ouverture").hide();
alerte("Une seule ouverture <u>de chaque type</u> par construction autorisée.");
}
}
});
/******************************* Gestion des clics dans la popup des ouvertures *********************************/
$(".popup-ouverture").click(function (e) {
e.preventDefault();
if ($(e.target).attr('id') == 'popup-alerte-annuler') {
$(".popup-ouverture").hide();
$("#overlay").hide();
unSelect();
return;
}
if (!$(e.target).parent().hasClass('disabled')) {
var nomTravee = extraireNomTravee($("#traveeSelectionnee").val());
var nomFace = extraireFace($("#traveeSelectionnee").val());
var nouvelleOuverture;
if ($(e.target).parent().attr('id') != 'PE+F1') {
nouvelleOuverture = creerOuverture(nomTravee, nomFace, $(e.target).parent().attr('id'));
traitementCreationOuverture(nomTravee, nomFace, nouvelleOuverture);
var faceOpposee = rechercherFaceOpposee(nomTravee, nomFace);
if (faceOpposee != null) {
nouvelleOuverture = creerOuverture(faceOpposee[0], faceOpposee[1], $(e.target).parent().attr('id'));
traitementCreationOuverture(faceOpposee[0], faceOpposee[1], nouvelleOuverture);
}
} else {
// Cas particulier du combo PE + F1 :
// on crée chacune de 2 ouvertures puis on régularise (nb d'ouvertures, score VT, etc...)
var ouvertures = creerComboOuvertures(nomTravee, nomFace);
traitementCreationOuverture(nomTravee, nomFace, ouvertures);
}
$(".popup-ouverture").hide();
$("#overlay").hide();
unSelect();
}
});
/********************************** Changement d'angle de vue ***********************************/
$("#changement-vue div").click(function (e) {
e.stopImmediatePropagation();
$("#changement-vue div").removeClass('actif');
var direction = $(e.target).parent().attr('id');
if (direction == "aerien") {
afficherVueAerienne();
} else {
$(e.target).parent().addClass('actif');
changePointOfView(direction);
}
});
$("#transparent-overlay").click(function (e) {
e.preventDefault();
if ($("#transparent-overlay").is(":visible"))
alerte("Pour quitter cette vue, cliquez sur le bouton rouge.");
});
/******************************* Clic pour quitter le mode vue aérienne **************************************/
$("#quitter-vue-aerienne").click(function (e) {
e.preventDefault();
$("#vue-aerienne").hide();
if ($("#overlay").is(":visible")) $("#overlay").hide();
if ($("#transparent-overlay").is(":visible")) $("#transparent-overlay").hide();
$("div:contains('Open Controls')").click();
$("#changement-vue div#aerien").removeClass('surligne');
activeCamera = camera;
camera.position.set(60, 40, 160);
cameraOrtho.zoom = 1;
hideMainIncrustations();
// On raffiche toit et plancher
$("span:contains('afficherToit')").click();
$("span:contains('afficherPlancher')").click();
});
$("#zoom").click(function (e) {
if (cameraOrtho.zoom < 4)
cameraOrtho.zoom += 0.1;
e.stopImmediatePropagation();
// On redimensionne la police des incrustations
redimensionnerIncrustations();
});
$("#dezoom").click(function (e) {
if (cameraOrtho.zoom > 0.2)
cameraOrtho.zoom -= 0.1;
e.stopImmediatePropagation();
// On redimensionne la police des incrustations
redimensionnerIncrustations();
});
/********************************* Dans la vue d'implantation, affichage de la légende ****************************/
$("#boutons > #legende").click(function (e) {
e.preventDefault();
if (!$("#legende").is(":visible")) {
$("#legende").show();
// $("#overlay").show();
} else {
$("#legende").hide();
// $("#overlay").hide();
}
});
/********************************** Popup d'export de la scene *************************************************/
$("#popup-export-button").click(function (e) {
$("#popup-export").hide();
$("#overlay").hide();
$("#popup-export .texte").html(TEXTE_EXPORT);
});
/********************************** Popup de choix du sens de décalage *************************************************/
$("#popup-decalage-annuler").click(function (e) {
$("#popup-decalage").hide();
$("#overlay").hide();
});
$("#popup-decalage-arriere").click(function (e) {
$("#popup-decalage").hide();
$("#overlay").hide();
decalerTravee(PREFIXE_TRAVEE + nbTravees, 'back', false);
var travee = creerTravee();
if (travee) traitementCreationTravee(travee);
decalerTravee(PREFIXE_TRAVEE + (nbTravees - 1), 'front', false);
supprimerToutesOuvertures();
recreerTrappes();
});
$("#popup-decalage-avant").click(function (e) {
$("#popup-decalage").hide();
$("#overlay").hide();
decalerTravee(PREFIXE_TRAVEE + nbTravees, 'front', false);
var travee = creerTravee();
if (travee) traitementCreationTravee(travee);
decalerTravee(PREFIXE_TRAVEE + (nbTravees - 1), 'back', false);
supprimerToutesOuvertures();
recreerTrappes();
});
/*****************************************************************************************************************************/
/* Petit easter-egg : le double-clic sur le logo Maninghem affiche des logs complètes dans la console */
$(".image-logo").dblclick(function (e) {
e.stopImmediatePropagation();
log("tableauTravees[] = ");
log(tableauTravees);
log("inventaire[] = ");
log(inventaire);
log("objetsModifiables[] = ");
log(objetsModifiables);
showMainIncrustations();
showPignonIncrustations();
});
/****************************************************************************************************************/
export function onMouseDoubleClick(event) {
var objetTouche, faceTouchee;
var FACE_EXTERNE = 10;
if ($("#vue-aerienne").css("display") == "flex") return;
if ($("#quitter-vue-aerienne").is(":visible")) return;
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
mouse.left = event.pageX;
mouse.top = event.pageY;
raycaster.setFromCamera(mouse, camera);
// Il faut penser à rajouter les objets sur lesquels on veut pouvoir cliquer dans objetsModifiables[]
var intersects = raycaster.intersectObjects(objetsModifiables, true);
if (intersects.length === 0) { // On clique en-dehors d'un objet cliquable.
unSelect();
return;
}
if (DEBUG) {
log('Vous avez cliqué sur : ');
log(intersects);
}
// Pour éviter les intersections alors que le menu contextuel est affiché.
if ($('#div-menu-contextuel').css('opacity') == 1) return;
objetTouche = intersects[0].object;
faceTouchee = intersects[0].faceIndex;
// On n'intercepte volontairement pas certains objets
if (objetTouche.name.includes('excluded')) return; // Pour exclure certains objets de l'intersection (ex : cadre des fenêtres ou toit)
// Pour le cas particulier du toit, qui doit laisser passer le raycast, on recherche le prochain objet ni transparent ni exclu.
var trouve = false;
if (objetTouche.name.includes('transparent')) {
for (var i = 1; i < intersects.length; i++) {
if (!intersects[i].object.name.includes('transparent') && !intersects[i].object.name.includes('excluded')) {
objetTouche = intersects[i].object;
faceTouchee = intersects[i].faceIndex;
trouve = true;
break;
}
}
if (!trouve) return;
}
// S'il existe déjà une précédente sélection, on l'efface.
if (facesSelectionnees.length > 0) unSelect()
var face = Math.floor(faceTouchee / 2); // Bidouille pour pouvoir sélectionner les 2 faces composant une façade.
for (var j = 0; j < 2; j++) {
var numFace = face * 2 + j;
// Suivant l'objet touché...
if (!objetTouche.parent.name.includes('>')) { // Un mur
objetTouche.geometry.faces[numFace].color.set(COLOR_ARRAY['highlight']);
} else {
if (objetTouche.name.includes('Portique'))
objetTouche.geometry.faces[numFace].color.set(COLOR_ARRAY['highlight']);
if (objetTouche.name.includes('Vitre'))
objetTouche.material = selectedGlassMaterial;
if (objetTouche.name.includes('Porte'))
objetTouche.material = selectedDoorMaterial;
if (objetTouche.name.includes('PINT')) { // Pignon intérieur
for (var k = 0; k < 12; k++) {
objetTouche.geometry.faces[k].color.set(COLOR_ARRAY['highlight']);
}
}
}
objetTouche.geometry.elementsNeedUpdate = true;
facesSelectionnees.push(numFace);
var modeOssatureBois = $("span:contains('ossatureBois')").parent().find("input[type='checkbox']").prop('checked');
var ouvertureDansMur;
/* En mode "Ossature bois", il n'est pas possible de sélectionner une ouverture (puisqu'elles n'apparaissent pas) donc, en cas de sélection d'un mur possédant une ouverture, on présume que c'est sur l'ouverture que l'on veut jouer. */
if (modeOssatureBois) {
ouvertureDansMur = false;
// On recherche s'il existe une ouverture sur ce mur
for (var objet in objetsModifiables) {
if (objetsModifiables[objet].name.indexOf(objetTouche.name + '>Ouverture ') != -1) {
for (var child in objetsModifiables[objet].children) {
if (objetsModifiables[objet].children[child].name != "excluded") {
objetSelectionne = objetsModifiables[objet].children[child].name;
ouvertureDansMur = true;
break;
}
}
}
}
if (ouvertureDansMur) {
var nouvelObjetTouche = scene.getObjectByName(objetSelectionne);
info(traduireNomObjet(nouvelObjetTouche));
displayContextualMenu(nouvelObjetTouche, mouse.left, mouse.top);
}
}
if (!modeOssatureBois || (modeOssatureBois && !ouvertureDansMur)) {
objetSelectionne = objetTouche.name;
info(traduireNomObjet(objetTouche));
displayContextualMenu(objetTouche, mouse.left, mouse.top);
}
}
}
export function onMouseClick(event) {
if (!event.srcElement.localName == 'a') event.preventDefault();
if ($(".div-aide").hasClass("affiche")) $(".div-aide").removeClass("affiche");
if (activeCamera != camera)
camera.zoom = 1;
$("#changement-vue div").removeClass("actif");
}
export function onMouseMove(event) {
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
mouse.left = event.pageX;
mouse.top = event.pageY;
if (DEBUG) {
var intersects = raycaster.intersectObjects(objetsModifiables, true);
alerte(intersects[0].name);
}
}
export function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
/***********************************************/
export function keyPressed(e) {
unSelect();
}

1043
js/gui.js Executable file

File diff suppressed because it is too large Load Diff

14
js/helpers.js Executable file
View File

@@ -0,0 +1,14 @@
import {
rearLight,
frontLight
} from "./environment.js"
// Aide au debug
var lightHelper1 = new THREE.DirectionalLightHelper(rearLight, 5);
var lightHelper2 = new THREE.SpotLightHelper(frontLight, 5);
scene.add(lightHelper1);
scene.add(lightHelper2);
var axesHelper = new THREE.AxesHelper(100);
scene.add(axesHelper);

20
js/html2canvas.min.js vendored Executable file

File diff suppressed because one or more lines are too long

2
js/jquery-3.4.1.min.js vendored Executable file

File diff suppressed because one or more lines are too long

357
js/jsreport.js Executable file
View File

@@ -0,0 +1,357 @@
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
var saveAs=saveAs||function(e){"use strict";if(typeof e==="undefined"||typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),o="download"in r,a=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},i=/constructor/i.test(e.HTMLElement)||e.safari,f=/CriOS\/[\d]+/.test(navigator.userAgent),u=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},s="application/octet-stream",d=1e3*40,c=function(e){var t=function(){if(typeof e==="string"){n().revokeObjectURL(e)}else{e.remove()}};setTimeout(t,d)},l=function(e,t,n){t=[].concat(t);var r=t.length;while(r--){var o=e["on"+t[r]];if(typeof o==="function"){try{o.call(e,n||e)}catch(a){u(a)}}}},p=function(e){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)){return new Blob([String.fromCharCode(65279),e],{type:e.type})}return e},v=function(t,u,d){if(!d){t=p(t)}var v=this,w=t.type,m=w===s,y,h=function(){l(v,"writestart progress write writeend".split(" "))},S=function(){if((f||m&&i)&&e.FileReader){var r=new FileReader;r.onloadend=function(){var t=f?r.result:r.result.replace(/^data:[^;]*;/,"data:attachment/file;");var n=e.open(t,"_blank");if(!n)e.location.href=t;t=undefined;v.readyState=v.DONE;h()};r.readAsDataURL(t);v.readyState=v.INIT;return}if(!y){y=n().createObjectURL(t)}if(m){e.location.href=y}else{var o=e.open(y,"_blank");if(!o){e.location.href=y}}v.readyState=v.DONE;h();c(y)};v.readyState=v.INIT;if(o){y=n().createObjectURL(t);setTimeout(function(){r.href=y;r.download=u;a(r);h();c(y);v.readyState=v.DONE});return}S()},w=v.prototype,m=function(e,t,n){return new v(e,t||e.name||"download",n)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(e,t,n){t=t||e.name||"download";if(!n){e=p(e)}return navigator.msSaveOrOpenBlob(e,t)}}w.abort=function(){};w.readyState=w.INIT=0;w.WRITING=1;w.DONE=2;w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null;return m}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!==null){define("FileSaver.js",function(){return saveAs})}/* globals jsreportInit define saveAs */
/* eslint-env browser */
;
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : global.jsreport = factory()
}(this, function () {
'use strict'
function JsReport () {
this.options = {}
this.headers = this.headers || {}
}
function isObject (value) {
var type = typeof value
return type === 'function' || (value && type === 'object') || false
}
function responseToString (response) {
// String.fromCharCode.apply(null, new Uint8Array(response)) was too slow
// see https://github.com/jsreport/jsreport-browser-client-dist/issues/4
var array = new Uint8Array(response)
var res = ''
for (var i = 0; i < array.length; i++) {
res += String.fromCharCode(array[i])
}
return res
}
function _serverSideRender (request, placeholder) {
var frameName = placeholder || '_blank'
if (placeholder && (placeholder !== '_blank' && placeholder !== '_top' && placeholder !== '_parent' && placeholder !== '_self')) {
if (typeof placeholder === 'string' || placeholder instanceof String) {
var contentIframe = document.getElementById('contentIframe')
if (contentIframe) {
var contentIframeDoc = contentIframe.contentDocument || contentIframe.contentWindow.document
placeholder = contentIframeDoc.getElementById(placeholder)
} else {
placeholder = document.getElementById(placeholder)
}
}
if (placeholder.length) {
placeholder = placeholder[0]
}
frameName = request.template.shortid || new Date().getTime()
var iframe = "<iframe frameborder='0' name='" + frameName + "' style='width:100%;height:100%;z-index:50'></iframe>"
placeholder.innerHTML = iframe
}
var mapForm = document.createElement('form')
mapForm.target = frameName
mapForm.id = new Date().getTime()
mapForm.method = 'POST'
mapForm.action = this.serverUrl + '/api/report'
function addInput (form, name, value) {
var input = document.createElement('input')
input.type = 'hidden'
input.name = name
input.value = value
form.appendChild(input)
}
function addBody (path, body) {
if (body === undefined) {
return
}
for (var key in body) {
if (isObject(body[key])) {
// somehow it skips empty array for template.scripts, this condition fixes that
if (body[key] instanceof Array && body[key].length === 0) {
addInput(mapForm, path + '[' + key + ']', [])
}
addBody(path + '[' + key + ']', body[key])
} else {
if (body[key] !== undefined && !(body[key] instanceof Array)) {
addInput(mapForm, path + '[' + key + ']', body[key])
}
}
}
}
addBody('template', request.template)
if (request.options != null) {
addBody('options', request.options)
}
if (request.data) {
addBody('data', request.data)
}
var headers = this.headers
headers['host-cookie'] = document.cookie
addBody('headers', headers)
document.body.appendChild(mapForm)
function submit (i) {
if (i > 10) {
return console.log('Unable to submit render form.')
}
try {
mapForm.submit()
mapForm.outerHTML = ''
} catch (e) {
setTimeout(function () {
submit(i + 1)
}, 50)
}
}
submit(0)
}
function _render (placeholder, request) {
var self = this
if (!this.serverUrl) {
throw new Error('The script was not linked from jsreport. You need to fill jsreport.serverUrl property with valid url to jsreport server.')
}
if (!request) {
request = placeholder
placeholder = '_blank'
}
if (typeof request === 'string' || request instanceof String) {
request = {
template: { shortid: request }
}
}
if (!request.template) {
request = { template: request }
}
_serverSideRender.call(self, request, placeholder)
}
function _renderAsync (request) {
var self = this
if (!this.serverUrl) {
throw new Error('The script was not linked from jsreport. You need to fill jsreport.serverUrl property with valid url to jsreport server.')
}
if (!request.template) {
request = { template: request }
}
var xhr = new XMLHttpRequest()
var data = JSON.stringify(request)
xhr.open('POST', this.serverUrl + '/api/report', true)
xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8')
Object.keys(this.headers).forEach(function (k) {
xhr.setRequestHeader(k, self.headers[k])
})
xhr.responseType = 'arraybuffer'
var PromiseImpl = this.promise || window.Promise || undefined
if (!PromiseImpl) {
throw new Error('Native Promise is not supported in this browser. Use jsreport.Promise = bluebirdOrAnyOtherLib;')
}
return new PromiseImpl(function (resolve, reject) {
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
var response = xhr.response
response.xhr = xhr
response.toString = function () {
return decodeURIComponent(escape(responseToString(response)))
}
response.toDataURI = function () {
var contentType = xhr.getResponseHeader('Content-Type')
var base64 = window.btoa(responseToString(response))
return 'data:' + contentType + ';base64, ' + base64
}
response.toObjectURL = function () {
return URL.createObjectURL(response.toBlob())
}
response.toBlob = function () {
var contentType = xhr.getResponseHeader('Content-Type')
var dataView = new DataView(response)
var blob
try {
blob = new Blob([dataView], { type: contentType })
} catch (e) {
if (e.name === 'InvalidStateError') {
var byteArray = new Uint8Array(response)
blob = new Blob([byteArray.buffer], { type: contentType })
} else {
throw e
}
}
return blob
}
response.download = function (afilename) {
saveAs(response.toBlob(), afilename)
}
resolve(response)
} else {
var error
try {
var body = responseToString(xhr.response)
error = JSON.parse(body)
} catch (e) {
}
reject({
status: this.status,
statusText: xhr.statusText,
error: error,
response: xhr.response
})
}
}
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
})
}
xhr.send(data)
})
}
function _request (req) {
var self = this
var xhr = new XMLHttpRequest()
xhr.open(req.method, this.serverUrl + req.path, true)
xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8')
Object.keys(this.headers).forEach(function (k) {
xhr.setRequestHeader(k, self.headers[k])
})
var PromiseImpl = this.promise || window.Promise || undefined
if (!PromiseImpl) {
throw new Error('Native Promise is not supported in this browser. Use jsreport.Promise = bluebirdOrAnyOtherLib;')
}
return new PromiseImpl(function (resolve, reject) {
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
if (xhr.response) {
return resolve(JSON.parse(xhr.response))
}
resolve(xhr.response)
} else {
reject({
status: this.status,
statusText: xhr.statusText
})
}
}
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
})
}
xhr.send(req.data ? JSON.stringify(req.data) : undefined)
})
}
JsReport.prototype = {
render: function (placeholder, request) {
return _render.call(this, placeholder, request)
},
download: function (filename, request) {
request.options = request.options || {}
request.options['Content-Disposition'] = 'attachment;filename=' + filename
return _render.call(this, '_self', request)
},
getTemplateByName: function (name) {
return _request.call(this, {
method: 'GET',
path: '/odata/templates?$filter=name' + encodeURI(" eq '" + name + "'")
}).then(function (r) {
if (r.value.length === 0) {
throw new Error('Template ' + name + ' not found')
}
return r.value[0]
})
},
updateTemplate: function (template) {
return _request.call(this, { method: 'PATCH', path: '/odata/templates(' + template._id + ')', data: template })
},
renderAsync: function (request) {
return _renderAsync.call(this, request)
}
}
var jsreportInstance = new JsReport()
setTimeout(function () {
if (window.jsreportInit !== undefined) {
jsreportInit(jsreportInstance)
}
}, 0)
var assign = Object.assign
// polyfill for Object.assign
if (!assign) {
(function () {
assign = function (target) {
'use strict'
if (target === undefined || target === null) {
throw new TypeError('Cannot convert undefined or null to object')
}
var output = Object(target)
for (var index = 1; index < arguments.length; index++) {
var source = arguments[index]
if (source !== undefined && source !== null) {
for (var nextKey in source) {
if (source.hasOwnProperty(nextKey)) {
output[nextKey] = source[nextKey]
}
}
}
}
return output
}
})()
}
if (window.jsreport) {
Object.assign(jsreportInstance, window.jsreport)
}
return jsreportInstance
}))

1974
js/main.js Executable file

File diff suppressed because it is too large Load Diff

504
js/materials.js Executable file
View File

@@ -0,0 +1,504 @@
export var COLOR_ARRAY = new Array(THREE.Color);
COLOR_ARRAY['noir'] = (new THREE.Color(0x000000).convertSRGBToLinear());
COLOR_ARRAY['bleu_ciel'] = (new THREE.Color(0xc0dfff).convertSRGBToLinear());
COLOR_ARRAY['ral7016'] = (new THREE.Color(0x303438).convertSRGBToLinear());
COLOR_ARRAY['blanc'] = (new THREE.Color(0xffffff).convertSRGBToLinear());
COLOR_ARRAY['crepi'] = (new THREE.Color(0xf5f2e6).convertSRGBToLinear());
COLOR_ARRAY['marron'] = (new THREE.Color(0x744b35).convertSRGBToLinear());
COLOR_ARRAY['bois'] = (new THREE.Color(0xfce7dc).convertSRGBToLinear());
COLOR_ARRAY['gris_clair'] = (new THREE.Color(0xb3b7b3).convertSRGBToLinear());
COLOR_ARRAY['vert'] = (new THREE.Color(0x55a06d).convertSRGBToLinear());
COLOR_ARRAY['highlight'] = (new THREE.Color(0xfd6868).convertSRGBToLinear());
COLOR_ARRAY['jaune'] = (new THREE.Color(0xfeffe7).convertSRGBToLinear());
var textureLoader = new THREE.TextureLoader();
// Pour l'affichage des côtes en surimpression
export var textMaterial = new THREE.MeshBasicMaterial({
color: COLOR_ARRAY['blanc']
});
export function createText(texte, taillePolice = 2) {
var cotes = new THREE.Mesh();
var loader = new THREE.FontLoader();
loader.load('fonts/helvetiker_regular.typeface.json', function (font) {
var geometry = new THREE.TextGeometry(texte, {
font: font,
size: taillePolice,
color: COLOR_ARRAY['blanc'],
height: 0.1,
curveSegments: 4,
bevelEnabled: false
});
cotes.geometry = geometry;
cotes.geometry.center();
cotes.material = textMaterial;
});
return cotes;
}
// Boussole
var boussoleTexture = textureLoader.load("icons/boussole.png");
boussoleTexture.encoding = THREE.sRGBEncoding;
export var boussoleMaterial = new THREE.MeshBasicMaterial({
map: boussoleTexture,
transparent: true,
color: COLOR_ARRAY['blanc']
});
// Sol gazonné
var groundTexture = textureLoader.load("img/textures/gazon2.jpg");
groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;
groundTexture.repeat.set(50, 50);
groundTexture.encoding = THREE.sRGBEncoding;
export var groundMaterial = new THREE.MeshLambertMaterial({
map: groundTexture,
reflectivity: 0.2,
color: COLOR_ARRAY['vert']
});
export var blankMaterial = new THREE.MeshBasicMaterial({
color: COLOR_ARRAY['blanc'],
});
// Toit
var roofTexture = textureLoader.load("img/textures/ardoise.jpg");
roofTexture.wrapS = roofTexture.wrapT = THREE.RepeatWrapping;
roofTexture.repeat.set(5, 5);
var roofExtMaterial = new THREE.MeshLambertMaterial({
map: roofTexture,
color: COLOR_ARRAY['gris_clair']
});
export var roofMaterial = [roofExtMaterial, roofExtMaterial, roofExtMaterial, roofExtMaterial, roofExtMaterial, roofExtMaterial];
// Pour tout type d'ouverture
export var windowMaterial = new THREE.MeshStandardMaterial({
color: COLOR_ARRAY['ral7016'],
roughness: 0.4,
metalness: 0.7,
side: THREE.DoubleSide
});
// Fenêtre
export var glassMaterial = new THREE.MeshPhongMaterial({
color: COLOR_ARRAY['bleu_ciel'],
shininess: 50,
specular: COLOR_ARRAY['bleu_ciel'],
refractionRatio: 0.7
});
export var selectedGlassMaterial = new THREE.MeshPhongMaterial({
color: COLOR_ARRAY['highlight'],
shininess: 20,
specular: COLOR_ARRAY['highlight'],
refractionRatio: 0.4
});
// Porte ou porte-fenêtre
export var doorMaterial = new THREE.MeshPhongMaterial({
color: COLOR_ARRAY['ral7016'],
shininess: 50,
specular: COLOR_ARRAY['ral7016'],
refractionRatio: 0.6
});
export var selectedDoorMaterial = new THREE.MeshPhongMaterial({
color: COLOR_ARRAY['highlight'],
shininess: 50,
specular: COLOR_ARRAY['ral7016'],
refractionRatio: 0.6
});
// Porte de garage
var garageDoorTexture = new THREE.Texture();
garageDoorTexture = textureLoader.load("img/textures/porte_garage.jpg");
export var garageDoorMaterial = new THREE.MeshLambertMaterial({
map: garageDoorTexture,
color: COLOR_ARRAY['ral7016']
});
// Travee
var wallTexture = textureLoader.load("img/textures/briques.jpg");
wallTexture.wrapS = wallTexture.wrapT = THREE.RepeatWrapping;
wallTexture.repeat.set(2, 2);
export var wallMaterial = new THREE.MeshLambertMaterial({
map: wallTexture,
color: COLOR_ARRAY['blanc'],
vertexColors: true
});
var pignonTexture = textureLoader.load("img/textures/briques.jpg");
pignonTexture.wrapS = pignonTexture.wrapT = THREE.RepeatWrapping;
pignonTexture.repeat.set(0.06, 0.08);
var pignonExtMaterial = new THREE.MeshLambertMaterial({
map: pignonTexture,
color: COLOR_ARRAY['blanc']
});
export var pignonMaterial = [pignonExtMaterial, pignonExtMaterial];
var floorTexture = textureLoader.load("img/textures/carrelage.jpg");
floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;
floorTexture.repeat.set(10, 20);
export var floorMaterial = new THREE.MeshBasicMaterial({
map: floorTexture,
reflectivity: 0.3,
color: COLOR_ARRAY['gris_clair']
});
/**************************************** Armatures bois *************************************************/
/************************ Planchers *******************/
var SOLP_Up_Texture = new THREE.Texture();
var SOLP_Down_Texture = new THREE.Texture();
var SOLP_Bump_Texture = new THREE.Texture();
SOLP_Up_Texture = textureLoader.load("img/openings/SOLP_U.png");
SOLP_Down_Texture = textureLoader.load("img/openings/SOLP_D.png");
SOLP_Bump_Texture = textureLoader.load("img/openings/SOLP_D_bump.png");
var SOLP_Up_Material = new THREE.MeshLambertMaterial({
map: SOLP_Up_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
var SOLP_Down_Material = new THREE.MeshStandardMaterial({
map: SOLP_Down_Texture,
bumpMap: SOLP_Bump_Texture,
color: COLOR_ARRAY['bois'],
transparent: true
});
export var SOLP_Material = [SOLP_Up_Material, SOLP_Up_Material, SOLP_Up_Material, SOLP_Up_Material, SOLP_Up_Material, SOLP_Down_Material];
var SOLE_1_Up_Texture = new THREE.Texture();
var SOLE_1_Down_Texture = new THREE.Texture();
var SOLE_1_Bump_Texture = new THREE.Texture();
SOLE_1_Up_Texture = textureLoader.load("img/openings/SOLE_1_U.png");
SOLE_1_Down_Texture = textureLoader.load("img/openings/SOLE_1_D.png");
SOLE_1_Bump_Texture = textureLoader.load("img/openings/SOLE_1_D_bump.png");
var SOLE_1_Up_Material = new THREE.MeshLambertMaterial({
map: SOLE_1_Up_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
var SOLE_1_Down_Material = new THREE.MeshStandardMaterial({
map: SOLE_1_Down_Texture,
bumpMap: SOLE_1_Bump_Texture,
color: COLOR_ARRAY['bois'],
transparent: true
});
export var SOLE_1_Material = [SOLE_1_Up_Material, SOLE_1_Up_Material, SOLE_1_Up_Material, SOLE_1_Up_Material, SOLE_1_Up_Material, SOLE_1_Down_Material];
var SOLE_2_Up_Texture = new THREE.Texture();
var SOLE_2_Down_Texture = new THREE.Texture();
var SOLE_2_Bump_Texture = new THREE.Texture();
SOLE_2_Up_Texture = textureLoader.load("img/openings/SOLE_2_U.png");
SOLE_2_Down_Texture = textureLoader.load("img/openings/SOLE_2_D.png");
SOLE_2_Bump_Texture = textureLoader.load("img/openings/SOLE_2_D_bump.png");
var SOLE_2_Up_Material = new THREE.MeshLambertMaterial({
map: SOLE_2_Up_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
var SOLE_2_Down_Material = new THREE.MeshStandardMaterial({
map: SOLE_2_Down_Texture,
bumpMap: SOLE_2_Bump_Texture,
color: COLOR_ARRAY['bois'],
transparent: true
});
export var SOLE_2_Material = [SOLE_2_Up_Material, SOLE_2_Up_Material, SOLE_2_Up_Material, SOLE_2_Up_Material, SOLE_2_Up_Material, SOLE_2_Down_Material];
var SOLT_Up_Texture = new THREE.Texture();
var SOLT_Down_Texture = new THREE.Texture();
var SOLT_Bump_Texture = new THREE.Texture();
SOLT_Up_Texture = textureLoader.load("img/openings/SOLT_U.png");
SOLT_Down_Texture = textureLoader.load("img/openings/SOLT_D.png");
SOLT_Bump_Texture = textureLoader.load("img/openings/SOLT_D_bump.png");
var SOLT_Up_Material = new THREE.MeshLambertMaterial({
map: SOLT_Up_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
var SOLT_Down_Material = new THREE.MeshStandardMaterial({
map: SOLT_Down_Texture,
bumpMap: SOLT_Bump_Texture,
color: COLOR_ARRAY['bois'],
transparent: true
});
export var SOLT_Material = [SOLT_Up_Material, SOLT_Up_Material, SOLT_Up_Material, SOLT_Up_Material, SOLT_Up_Material, SOLT_Down_Material];
/************************ Modules *******************/
/****** Mur plein ****/
var MPL_Front_Texture = textureLoader.load("img/openings/MPL_F.png");
var MPL_Front_Material = new THREE.MeshLambertMaterial({
map: MPL_Front_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois']
});
var MPL_Back_Texture = textureLoader.load("img/openings/MPL_B.png");
var MPL_Back_Material = new THREE.MeshLambertMaterial({
map: MPL_Back_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois']
});
export var MPL_Material = [MPL_Front_Material, MPL_Front_Material, MPL_Front_Material, MPL_Front_Material, MPL_Back_Material, MPL_Front_Material];
/****** Porte d'entrée ****/
var MPE_Front_Texture = textureLoader.load("img/openings/MPE_F.png");
var MPE_Front_Material = new THREE.MeshLambertMaterial({
map: MPE_Front_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
var MPE_Back_Texture = textureLoader.load("img/openings/MPE_B.png");
var MPE_Back_Material = new THREE.MeshLambertMaterial({
map: MPE_Back_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
export var MPE_Material = [MPL_Front_Material, MPL_Front_Material, MPL_Front_Material, MPL_Front_Material, MPE_Back_Material, MPE_Front_Material];
/****** Fenêtre de type F1 ****/
var MF1d_Front_Texture = textureLoader.load("img/openings/MF1d_F.png");
var MF1d_Front_Material = new THREE.MeshLambertMaterial({
map: MF1d_Front_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
var MF1d_Back_Texture = textureLoader.load("img/openings/MF1d_B.png");
var MF1d_Back_Material = new THREE.MeshLambertMaterial({
map: MF1d_Back_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
export var MF1d_Material = [MPL_Front_Material, MPL_Front_Material, MPL_Front_Material, MPL_Front_Material, MF1d_Back_Material, MF1d_Front_Material];
var MF1g_Front_Texture = textureLoader.load("img/openings/MF1g_F.png");
var MF1g_Front_Material = new THREE.MeshLambertMaterial({
map: MF1g_Front_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
var MF1g_Back_Texture = textureLoader.load("img/openings/MF1g_B.png");
var MF1g_Back_Material = new THREE.MeshLambertMaterial({
map: MF1g_Back_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
export var MF1g_Material = [MPL_Front_Material, MPL_Front_Material, MPL_Front_Material, MPL_Front_Material, MF1g_Back_Material, MF1g_Front_Material];
/****** Fenêtre de type F2 ****/
var MF2_Front_Texture = textureLoader.load("img/openings/MF2_F.png");
var MF2_Front_Material = new THREE.MeshLambertMaterial({
map: MF2_Front_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
var MF2_Back_Texture = textureLoader.load("img/openings/MF2_B.png");
var MF2_Back_Material = new THREE.MeshLambertMaterial({
map: MF2_Back_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
export var MF2_Material = [MPL_Front_Material, MPL_Front_Material, MPL_Front_Material, MPL_Front_Material, MF2_Back_Material, MF2_Front_Material];
/****** Combo porte d'entrée + fenêtre F1 ****/
var MPEF_Front_Texture = textureLoader.load("img/openings/MPEF_F.png");
var MPEF_Front_Material = new THREE.MeshLambertMaterial({
map: MPEF_Front_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
var MPEF_Back_Texture = textureLoader.load("img/openings/MPEF_B.png");
var MPEF_Back_Material = new THREE.MeshLambertMaterial({
map: MPEF_Back_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
export var MPEF_Material = [MPL_Front_Material, MPL_Front_Material, MPL_Front_Material, MPL_Front_Material, MPEF_Back_Material, MPEF_Front_Material];
/****** Porte-fenêtre ****/
var MPF_Front_Texture = textureLoader.load("img/openings/MPF_F.png");
var MPF_Front_Material = new THREE.MeshLambertMaterial({
map: MPF_Front_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
var MPF_Back_Texture = textureLoader.load("img/openings/MPF_B.png");
var MPF_Back_Material = new THREE.MeshLambertMaterial({
map: MPF_Back_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
export var MPF_Material = [MPL_Front_Material, MPL_Front_Material, MPL_Front_Material, MPL_Front_Material, MPF_Back_Material, MPF_Front_Material];
/****** Portique intérieur ****/
var MPI_Texture = textureLoader.load("img/openings/MPI.png");
MPI_Texture.wrapS = MPI_Texture.wrapT = THREE.RepeatWrapping;
MPI_Texture.repeat.set(0.5, 0.5);
var MPI_Material = new THREE.MeshLambertMaterial({
map: MPI_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
export var MPI_Material = [MPI_Material, MPI_Material, MPI_Material, MPI_Material, MPI_Material, MPI_Material];
/****** Portes de garage ****/
var MPG1_Front_Texture = textureLoader.load("img/openings/MPG1_F.png");
var MPG1_Front_Material = new THREE.MeshLambertMaterial({
map: MPG1_Front_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
var MPG1_Back_Texture = textureLoader.load("img/openings/MPG1_B.png");
var MPG1_Back_Material = new THREE.MeshLambertMaterial({
map: MPG1_Back_Texture,
vertexColors: true,
transparent: true,
color: COLOR_ARRAY['bois']
});
export var MPG1_Material = [MPL_Front_Material, MPL_Front_Material, MPL_Front_Material, MPL_Front_Material, MPG1_Back_Material, MPG1_Front_Material];
var MPG2_Front_Texture = textureLoader.load("img/openings/MPG2_F.png");
var MPG2_Front_Material = new THREE.MeshLambertMaterial({
map: MPG2_Front_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
var MPG2_Back_Texture = textureLoader.load("img/openings/MPG2_B.png");
var MPG2_Back_Material = new THREE.MeshLambertMaterial({
map: MPG2_Back_Texture,
vertexColors: true,
transparent: true,
color: COLOR_ARRAY['bois']
});
export var MPG2_Material = [MPL_Front_Material, MPL_Front_Material, MPL_Front_Material, MPL_Front_Material, MPG2_Back_Material, MPG2_Front_Material];
/************************* Pignons *****************************/
var PEXT_Front_Texture = textureLoader.load("img/openings/PEXT_F.png");
PEXT_Front_Texture.wrapS = PEXT_Front_Texture.wrapT = THREE.RepeatWrapping;
PEXT_Front_Texture.repeat.set(0.014, 0.037);
PEXT_Front_Texture.offset.set(0.5, 0);
var PEXT_Front_Material = new THREE.MeshLambertMaterial({
map: PEXT_Front_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois']
});
var PEXT_Back_Texture = textureLoader.load("img/openings/PEXT_B.png");
PEXT_Back_Texture.wrapS = PEXT_Back_Texture.wrapT = THREE.RepeatWrapping;
PEXT_Back_Texture.repeat.set(0.014, 0.037);
PEXT_Back_Texture.offset.set(0.5, 0);
var PEXT_Back_Material = new THREE.MeshLambertMaterial({
map: PEXT_Back_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois']
});
export var PEXT_Material = [PEXT_Front_Material, PEXT_Back_Material];
var PINT_Droite_Front_Texture = textureLoader.load("img/openings/PINT_droite_F.png");
PINT_Droite_Front_Texture.wrapS = PEXT_Front_Texture.wrapT = THREE.RepeatWrapping;
PINT_Droite_Front_Texture.repeat.set(0.013, 0.037);
PINT_Droite_Front_Texture.offset.set(0.5, 0);
var PINT_Droite_Front_Material = new THREE.MeshLambertMaterial({
map: PINT_Droite_Front_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
var PINT_Droite_Back_Texture = textureLoader.load("img/openings/PINT_droite_B.png");
PINT_Droite_Back_Texture.wrapS = PEXT_Back_Texture.wrapT = THREE.RepeatWrapping;
PINT_Droite_Back_Texture.repeat.set(0.013, 0.037);
PINT_Droite_Back_Texture.offset.set(0.5, 0);
var PINT_Droite_Back_Material = new THREE.MeshLambertMaterial({
map: PINT_Droite_Back_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
export var PINT_Droite_Material = [PINT_Droite_Front_Material, PINT_Droite_Back_Material];
var PINT_Gauche_Front_Texture = textureLoader.load("img/openings/PINT_gauche_F.png");
PINT_Gauche_Front_Texture.wrapS = PEXT_Front_Texture.wrapT = THREE.RepeatWrapping;
PINT_Gauche_Front_Texture.repeat.set(0.013, 0.037);
PINT_Gauche_Front_Texture.offset.set(0.5, 0);
var PINT_Gauche_Front_Material = new THREE.MeshLambertMaterial({
map: PINT_Gauche_Front_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
var PINT_Gauche_Back_Texture = textureLoader.load("img/openings/PINT_gauche_B.png");
PINT_Gauche_Back_Texture.wrapS = PEXT_Back_Texture.wrapT = THREE.RepeatWrapping;
PINT_Gauche_Back_Texture.repeat.set(0.013, 0.037);
PINT_Gauche_Back_Texture.offset.set(0.5, 0);
var PINT_Gauche_Back_Material = new THREE.MeshLambertMaterial({
map: PINT_Gauche_Back_Texture,
vertexColors: true,
color: COLOR_ARRAY['bois'],
transparent: true
});
export var PINT_Gauche_Material = [PINT_Gauche_Front_Material, PINT_Gauche_Back_Material];
/************************ Charpente *****************************/
var CH1T_Texture = textureLoader.load("img/openings/CH1T.png");
var CH1T_Top_Material = new THREE.MeshLambertMaterial({
map: CH1T_Texture,
color: COLOR_ARRAY['bois'],
transparent: true
});
export var CH1T_Material = [CH1T_Top_Material, CH1T_Top_Material, CH1T_Top_Material, CH1T_Top_Material, CH1T_Top_Material, CH1T_Top_Material];

1181
js/objects.js Executable file

File diff suppressed because it is too large Load Diff

1031
js/three.min.js vendored Executable file

File diff suppressed because one or more lines are too long

450
js/threex.domevents.js Executable file
View File

@@ -0,0 +1,450 @@
// This THREEx helper makes it easy to handle the mouse events in your 3D scene
//
// * CHANGES NEEDED
// * handle drag/drop
// * notify events not object3D - like DOM
// * so single object with property
// * DONE bubling implement bubling/capturing
// * DONE implement event.stopPropagation()
// * DONE implement event.type = "click" and co
// * DONE implement event.target
//
// # Lets get started
//
// First you include it in your page
//
// ```<script src='threex.domevent.js'>< /script>```
//
// # use the object oriented api
//
// You bind an event like this
//
// ```mesh.on('click', function(object3d){ ... })```
//
// To unbind an event, just do
//
// ```mesh.off('click', function(object3d){ ... })```
//
// As an alternative, there is another naming closer DOM events.
// Pick the one you like, they are doing the same thing
//
// ```mesh.addEventListener('click', function(object3d){ ... })```
// ```mesh.removeEventListener('click', function(object3d){ ... })```
//
// # Supported Events
//
// Always in a effort to stay close to usual pratices, the events name are the same as in DOM.
// The semantic is the same too.
// Currently, the available events are
// [click, dblclick, mouseup, mousedown](http://www.quirksmode.org/dom/events/click.html),
// [mouseover and mouse out](http://www.quirksmode.org/dom/events/mouseover.html).
//
// # use the standalone api
//
// The object-oriented api modifies THREE.Object3D class.
// It is a global class, so it may be legitimatly considered unclean by some people.
// If this bother you, simply do ```THREEx.DomEvents.noConflict()``` and use the
// standalone API. In fact, the object oriented API is just a thin wrapper
// on top of the standalone API.
//
// First, you instanciate the object
//
// ```var domEvent = new THREEx.DomEvent();```
//
// Then you bind an event like this
//
// ```domEvent.bind(mesh, 'click', function(object3d){ object3d.scale.x *= 2; });```
//
// To unbind an event, just do
//
// ```domEvent.unbind(mesh, 'click', callback);```
//
//
// # Code
//
/** @namespace */
var THREEx = THREEx || {};
// # Constructor
THREEx.DomEvents = function(camera, domElement)
{
this._camera = camera || null;
this._domElement= domElement || document;
this._raycaster = new THREE.Raycaster();
this._selected = null;
this._boundObjs = {};
// Bind dom event for mouse and touch
var _this = this;
this._$onClick = function(){ _this._onClick.apply(_this, arguments); };
this._$onDblClick = function(){ _this._onDblClick.apply(_this, arguments); };
this._$onMouseMove = function(){ _this._onMouseMove.apply(_this, arguments); };
this._$onMouseDown = function(){ _this._onMouseDown.apply(_this, arguments); };
this._$onMouseUp = function(){ _this._onMouseUp.apply(_this, arguments); };
this._$onTouchMove = function(){ _this._onTouchMove.apply(_this, arguments); };
this._$onTouchStart = function(){ _this._onTouchStart.apply(_this, arguments); };
this._$onTouchEnd = function(){ _this._onTouchEnd.apply(_this, arguments); };
this._$onContextmenu = function(){ _this._onContextmenu.apply(_this, arguments); };
this._domElement.addEventListener( 'click' , this._$onClick , false );
this._domElement.addEventListener( 'dblclick' , this._$onDblClick , false );
this._domElement.addEventListener( 'mousemove' , this._$onMouseMove , false );
this._domElement.addEventListener( 'mousedown' , this._$onMouseDown , false );
this._domElement.addEventListener( 'mouseup' , this._$onMouseUp , false );
this._domElement.addEventListener( 'touchmove' , this._$onTouchMove , false );
this._domElement.addEventListener( 'touchstart' , this._$onTouchStart , false );
this._domElement.addEventListener( 'touchend' , this._$onTouchEnd , false );
this._domElement.addEventListener( 'contextmenu', this._$onContextmenu , false );
}
// # Destructor
THREEx.DomEvents.prototype.destroy = function()
{
// unBind dom event for mouse and touch
this._domElement.removeEventListener( 'click' , this._$onClick , false );
this._domElement.removeEventListener( 'dblclick' , this._$onDblClick , false );
this._domElement.removeEventListener( 'mousemove' , this._$onMouseMove , false );
this._domElement.removeEventListener( 'mousedown' , this._$onMouseDown , false );
this._domElement.removeEventListener( 'mouseup' , this._$onMouseUp , false );
this._domElement.removeEventListener( 'touchmove' , this._$onTouchMove , false );
this._domElement.removeEventListener( 'touchstart' , this._$onTouchStart , false );
this._domElement.removeEventListener( 'touchend' , this._$onTouchEnd , false );
this._domElement.removeEventListener( 'contextmenu' , this._$onContextmenu , false );
}
THREEx.DomEvents.eventNames = [
"click",
"dblclick",
"mouseover",
"mouseout",
"mousemove",
"mousedown",
"mouseup",
"contextmenu",
"touchstart",
"touchend"
];
THREEx.DomEvents.prototype._getRelativeMouseXY = function(domEvent){
var element = domEvent.target || domEvent.srcElement;
if (element.nodeType === 3) {
element = element.parentNode; // Safari fix -- see http://www.quirksmode.org/js/events_properties.html
}
//get the real position of an element relative to the page starting point (0, 0)
//credits go to brainjam on answering http://stackoverflow.com/questions/5755312/getting-mouse-position-relative-to-content-area-of-an-element
var elPosition = { x : 0 , y : 0};
var tmpElement = element;
//store padding
var style = getComputedStyle(tmpElement, null);
elPosition.y += parseInt(style.getPropertyValue("padding-top"), 10);
elPosition.x += parseInt(style.getPropertyValue("padding-left"), 10);
//add positions
do {
elPosition.x += tmpElement.offsetLeft;
elPosition.y += tmpElement.offsetTop;
style = getComputedStyle(tmpElement, null);
elPosition.x += parseInt(style.getPropertyValue("border-left-width"), 10);
elPosition.y += parseInt(style.getPropertyValue("border-top-width"), 10);
} while(tmpElement = tmpElement.offsetParent);
var elDimension = {
width : (element === window) ? window.innerWidth : element.offsetWidth,
height : (element === window) ? window.innerHeight : element.offsetHeight
};
return {
x : +((domEvent.pageX - elPosition.x) / elDimension.width ) * 2 - 1,
y : -((domEvent.pageY - elPosition.y) / elDimension.height) * 2 + 1
};
};
/********************************************************************************/
/* domevent context */
/********************************************************************************/
// handle domevent context in object3d instance
THREEx.DomEvents.prototype._objectCtxInit = function(object3d){
object3d._3xDomEvent = {};
}
THREEx.DomEvents.prototype._objectCtxDeinit = function(object3d){
delete object3d._3xDomEvent;
}
THREEx.DomEvents.prototype._objectCtxIsInit = function(object3d){
return object3d._3xDomEvent ? true : false;
}
THREEx.DomEvents.prototype._objectCtxGet = function(object3d){
return object3d._3xDomEvent;
}
/********************************************************************************/
/* */
/********************************************************************************/
/**
* Getter/Setter for camera
*/
THREEx.DomEvents.prototype.camera = function(value)
{
if( value ) this._camera = value;
return this._camera;
}
THREEx.DomEvents.prototype.bind = function(object3d, eventName, callback, useCapture)
{
console.assert( THREEx.DomEvents.eventNames.indexOf(eventName) !== -1, "not available events:"+eventName );
if( !this._objectCtxIsInit(object3d) ) this._objectCtxInit(object3d);
var objectCtx = this._objectCtxGet(object3d);
if( !objectCtx[eventName+'Handlers'] ) objectCtx[eventName+'Handlers'] = [];
objectCtx[eventName+'Handlers'].push({
callback : callback,
useCapture : useCapture
});
// add this object in this._boundObjs
if( this._boundObjs[eventName] === undefined ){
this._boundObjs[eventName] = [];
}
this._boundObjs[eventName].push(object3d);
}
THREEx.DomEvents.prototype.addEventListener = THREEx.DomEvents.prototype.bind
THREEx.DomEvents.prototype.unbind = function(object3d, eventName, callback, useCapture)
{
console.assert( THREEx.DomEvents.eventNames.indexOf(eventName) !== -1, "not available events:"+eventName );
if( !this._objectCtxIsInit(object3d) ) this._objectCtxInit(object3d);
var objectCtx = this._objectCtxGet(object3d);
if( !objectCtx[eventName+'Handlers'] ) objectCtx[eventName+'Handlers'] = [];
var handlers = objectCtx[eventName+'Handlers'];
for(var i = 0; i < handlers.length; i++){
var handler = handlers[i];
if( callback != handler.callback ) continue;
if( useCapture != handler.useCapture ) continue;
handlers.splice(i, 1)
break;
}
// from this object from this._boundObjs
var index = this._boundObjs[eventName].indexOf(object3d);
console.assert( index !== -1 );
this._boundObjs[eventName].splice(index, 1);
}
THREEx.DomEvents.prototype.removeEventListener = THREEx.DomEvents.prototype.unbind
THREEx.DomEvents.prototype._bound = function(eventName, object3d)
{
var objectCtx = this._objectCtxGet(object3d);
if( !objectCtx ) return false;
return objectCtx[eventName+'Handlers'] ? true : false;
}
/********************************************************************************/
/* onMove */
/********************************************************************************/
// # handle mousemove kind of events
THREEx.DomEvents.prototype._onMove = function(eventName, mouseX, mouseY, origDomEvent)
{
//console.log('eventName', eventName, 'boundObjs', this._boundObjs[eventName])
// get objects bound to this event
var boundObjs = this._boundObjs[eventName];
if( boundObjs === undefined || boundObjs.length === 0 ) return;
// compute the intersection
var vector = new THREE.Vector2();
// update the picking ray with the camera and mouse position
vector.set( mouseX, mouseY );
this._raycaster.setFromCamera( vector, this._camera );
var intersects = this._raycaster.intersectObjects( boundObjs );
var oldSelected = this._selected;
if( intersects.length > 0 ){
var notifyOver, notifyOut, notifyMove;
var intersect = intersects[ 0 ];
var newSelected = intersect.object;
this._selected = newSelected;
// if newSelected bound mousemove, notify it
notifyMove = this._bound('mousemove', newSelected);
if( oldSelected != newSelected ){
// if newSelected bound mouseenter, notify it
notifyOver = this._bound('mouseover', newSelected);
// if there is a oldSelect and oldSelected bound mouseleave, notify it
notifyOut = oldSelected && this._bound('mouseout', oldSelected);
}
}else{
// if there is a oldSelect and oldSelected bound mouseleave, notify it
notifyOut = oldSelected && this._bound('mouseout', oldSelected);
this._selected = null;
}
// notify mouseMove - done at the end with a copy of the list to allow callback to remove handlers
notifyMove && this._notify('mousemove', newSelected, origDomEvent, intersect);
// notify mouseEnter - done at the end with a copy of the list to allow callback to remove handlers
notifyOver && this._notify('mouseover', newSelected, origDomEvent, intersect);
// notify mouseLeave - done at the end with a copy of the list to allow callback to remove handlers
notifyOut && this._notify('mouseout' , oldSelected, origDomEvent, intersect);
}
/********************************************************************************/
/* onEvent */
/********************************************************************************/
// # handle click kind of events
THREEx.DomEvents.prototype._onEvent = function(eventName, mouseX, mouseY, origDomEvent)
{
//console.log('eventName', eventName, 'boundObjs', this._boundObjs[eventName])
// get objects bound to this event
var boundObjs = this._boundObjs[eventName];
if( boundObjs === undefined || boundObjs.length === 0 ) return;
// compute the intersection
var vector = new THREE.Vector2();
// update the picking ray with the camera and mouse position
vector.set( mouseX, mouseY );
this._raycaster.setFromCamera( vector, this._camera );
var intersects = this._raycaster.intersectObjects( boundObjs, true);
// if there are no intersections, return now
if( intersects.length === 0 ) return;
// init some variables
var intersect = intersects[0];
var object3d = intersect.object;
var objectCtx = this._objectCtxGet(object3d);
var objectParent = object3d.parent;
while ( typeof(objectCtx) == 'undefined' && objectParent )
{
objectCtx = this._objectCtxGet(objectParent);
objectParent = objectParent.parent;
}
if( !objectCtx ) return;
// notify handlers
this._notify(eventName, object3d, origDomEvent, intersect);
}
THREEx.DomEvents.prototype._notify = function(eventName, object3d, origDomEvent, intersect)
{
var objectCtx = this._objectCtxGet(object3d);
var handlers = objectCtx ? objectCtx[eventName+'Handlers'] : null;
// parameter check
console.assert(arguments.length === 4)
// do bubbling
if( !objectCtx || !handlers || handlers.length === 0 ){
object3d.parent && this._notify(eventName, object3d.parent, origDomEvent, intersect);
return;
}
// notify all handlers
var handlers = objectCtx[eventName+'Handlers'];
for(var i = 0; i < handlers.length; i++){
var handler = handlers[i];
var toPropagate = true;
handler.callback({
type : eventName,
target : object3d,
origDomEvent : origDomEvent,
intersect : intersect,
stopPropagation : function(){
toPropagate = false;
}
});
if( !toPropagate ) continue;
// do bubbling
if( handler.useCapture === false ){
object3d.parent && this._notify(eventName, object3d.parent, origDomEvent, intersect);
}
}
}
/********************************************************************************/
/* handle mouse events */
/********************************************************************************/
// # handle mouse events
THREEx.DomEvents.prototype._onMouseDown = function(event){ return this._onMouseEvent('mousedown', event); }
THREEx.DomEvents.prototype._onMouseUp = function(event){ return this._onMouseEvent('mouseup' , event); }
THREEx.DomEvents.prototype._onMouseEvent = function(eventName, domEvent)
{
var mouseCoords = this._getRelativeMouseXY(domEvent);
this._onEvent(eventName, mouseCoords.x, mouseCoords.y, domEvent);
}
THREEx.DomEvents.prototype._onMouseMove = function(domEvent)
{
var mouseCoords = this._getRelativeMouseXY(domEvent);
this._onMove('mousemove', mouseCoords.x, mouseCoords.y, domEvent);
this._onMove('mouseover', mouseCoords.x, mouseCoords.y, domEvent);
this._onMove('mouseout' , mouseCoords.x, mouseCoords.y, domEvent);
}
THREEx.DomEvents.prototype._onClick = function(event)
{
// TODO handle touch ?
this._onMouseEvent('click' , event);
}
THREEx.DomEvents.prototype._onDblClick = function(event)
{
// TODO handle touch ?
this._onMouseEvent('dblclick' , event);
}
THREEx.DomEvents.prototype._onContextmenu = function(event)
{
//TODO don't have a clue about how this should work with touch..
this._onMouseEvent('contextmenu' , event);
}
/********************************************************************************/
/* handle touch events */
/********************************************************************************/
// # handle touch events
THREEx.DomEvents.prototype._onTouchStart = function(event){ return this._onTouchEvent('touchstart', event); }
THREEx.DomEvents.prototype._onTouchEnd = function(event){ return this._onTouchEvent('touchend' , event); }
THREEx.DomEvents.prototype._onTouchMove = function(domEvent)
{
if( domEvent.touches.length != 1 ) return undefined;
domEvent.preventDefault();
var mouseX = +(domEvent.touches[ 0 ].pageX / window.innerWidth ) * 2 - 1;
var mouseY = -(domEvent.touches[ 0 ].pageY / window.innerHeight) * 2 + 1;
this._onMove('mousemove', mouseX, mouseY, domEvent);
this._onMove('mouseover', mouseX, mouseY, domEvent);
this._onMove('mouseout' , mouseX, mouseY, domEvent);
}
THREEx.DomEvents.prototype._onTouchEvent = function(eventName, domEvent)
{
if( domEvent.touches.length != 1 ) return undefined;
domEvent.preventDefault();
var mouseX = +(domEvent.touches[ 0 ].pageX / window.innerWidth ) * 2 - 1;
var mouseY = -(domEvent.touches[ 0 ].pageY / window.innerHeight) * 2 + 1;
this._onEvent(eventName, mouseX, mouseY, domEvent);
}