Update main.js

This commit is contained in:
Beatrycze Volk 2022-08-31 18:53:38 +02:00
parent 60de3954bd
commit 744257202f
2 changed files with 312 additions and 133 deletions

View File

@ -1,5 +1,3 @@
{
"imports": {
"three": "/typo3conf/ext/dlf/Resources/Public/Javascript/3DViewer/build/three.module.js"
}
"imports": {
"three": "./build/three.module.js"
}

View File

@ -22,15 +22,15 @@ import { ColladaLoader } from './js/jsm/loaders/ColladaLoader.js';
import { STLLoader } from './js/jsm/loaders/STLLoader.js';
import { XYZLoader } from './js/jsm/loaders/XYZLoader.js';
import { TDSLoader } from './js/jsm/loaders/TDSLoader.js';
/*if (supportedFormats.indexOf(extension.toUpperCase()) < 0) {
return
}*/
import { PCDLoader } from './js/jsm/loaders/PCDLoader.js';
import { FontLoader } from './js/jsm/loaders/FontLoader.js';
import { TextGeometry } from './js/jsm/geometries/TextGeometry.js';
let camera, scene, renderer, stats, controls, loader, ambientLight, dirLight, dirLightTarget;
let imported;
var mainObject = [];
var metadataContentTech;
var mainCanvas;
var distanceGeometry = new THREE.Vector3();
let wisskiID = '';
@ -43,10 +43,19 @@ let mixer;
const container = document.getElementById("DFG_3DViewer");
container.setAttribute("width", window.self.innerWidth);
container.setAttribute("height", window.self.innerHeight);
const supportedFormats = [ 'OBJ', 'DAE', 'FBX', 'PLY', 'IFC', 'STL', 'XYZ', 'PCD', 'JSON', '3DS', 'GLFT' ];
container.setAttribute("display", "flex");
const originalPath = container.getAttribute("3d");
const proxyPath = container.getAttribute("proxy");
const wisskiUrl = container.getAttribute("wisski_url");
var elementsURL;
if (!proxyPath) {
elementsURL = window.location.pathname.match("/wisski/navigate/(.*)/view");
wisskiID = parseInt(elementsURL[1]);
container.setAttribute("wisski_id", wisskiID);
} else {
elementsURL = wisskiUrl.match("/export_xml_single/(.*)?page");
wisskiID = parseInt(elementsURL[1]);
}
const filename = container.getAttribute("3d").split("/").pop();
const basename = filename.substring(0, filename.lastIndexOf('.'));
const extension = filename.substring(filename.lastIndexOf('.') + 1);
@ -58,12 +67,9 @@ var COPYRIGHTS = false;
const allowedFormats = ['obj', 'fbx', 'ply', 'dae', 'ifc', 'stl', 'xyz', 'pcd', 'json', '3ds'];
var EXIT_CODE=1;
var gridSize;
var clippingMode=false;
var elementsURL = wisskiUrl;
elementsURL = elementsURL.match("/export_xml_single/(.*)?page");
wisskiID = elementsURL[1];
var canvasText;
var downloadModel, viewEntity, fullscreenMode;
var spinnerContainer = document.createElement("div");
spinnerContainer.id = 'spinnerContainer';
@ -83,8 +89,8 @@ container.appendChild(spinnerContainer);
var statsContainer = document.createElement("div");
statsContainer.id = 'statsContainer';
statsContainer.className = 'statsContainer';
statsContainer.style.position = 'relative';
statsContainer.style.right = '93%';
statsContainer.style.position = 'absolute';
statsContainer.style.left = '3%';
container.appendChild(statsContainer);
var guiContainer = document.createElement("div");
@ -94,9 +100,9 @@ guiContainer.style.position = 'absolute';
guiContainer.style.right = '2%';
guiContainer.style.marginTop = '0px';
var guiElement = document.createElement("div");
guiElement.id = 'guiContainer';
guiElement.className = 'guiContainer';
guiElement.appendChild(guiContainer);
guiElement.id = 'guiElement';
guiElement.className = 'guiElement';
guiContainer.appendChild(guiElement);
container.appendChild(guiContainer);
let spinner = new lv();
@ -145,6 +151,8 @@ const saveProperties = {
};
var EDITOR = false;
const lineMaterial = new THREE.LineBasicMaterial( { color: 0x0000ff } );
const linePoints = [];
const gui = new GUI({ container: guiContainer });
//const mainHierarchyFolder = gui.addFolder('Hierarchy');
@ -199,12 +207,13 @@ var planeObjects = [];
var clippingGeometry = [];
var textMesh;
var ruler;
function readWissKI () {
const xmlhttp = new XMLHttpRequest();
xmlhttp.onload = function() {
console.log(this.responseText);
}
};
xmlhttp.open("GET", "php/fetchWissKI.php?q=");
xmlhttp.send();
}
@ -264,7 +273,7 @@ function addTextWatermark (_text, _scale) {
];
const loader = new FontLoader();
loader.load( '/modules/dfg_3dviewer/main/fonts/helvetiker_regular.typeface.json', function ( font ) {
loader.load( '/typo3conf/ext/dlf/Resources/Public/Javascript/3DViewer/fonts/helvetiker_regular.typeface.json', function ( font ) {
const textGeo = new TextGeometry( _text, {
font: font,
@ -279,7 +288,7 @@ function addTextWatermark (_text, _scale) {
} );
textGeo.computeBoundingBox();
const centerOffset = - 0.5 * ( textGeo.boundingBox.max.x - textGeo.boundingBox.min.x );
//const centerOffset = - 0.5 * ( textGeo.boundingBox.max.x - textGeo.boundingBox.min.x );
textMesh = new THREE.Mesh( textGeo, materials );
@ -294,6 +303,42 @@ function addTextWatermark (_text, _scale) {
} );
}
function addTextPoint (_text, _scale, _point) {
var textGeo;
var materials = [
new THREE.MeshStandardMaterial( { color: 0x0000ff, flatShading: true, side: THREE.DoubleSide, depthTest: false, depthWrite: false, transparent: true, opacity: 0.4 } ), // front
new THREE.MeshStandardMaterial( { color: 0x0000ff, flatShading: true, side: THREE.DoubleSide, depthTest: false, depthWrite: false, transparent: true, opacity: 0.4 } ) // side
];
const loader = new FontLoader();
loader.load( '/typo3conf/ext/dlf/Resources/Public/Javascript/3DViewer/fonts/helvetiker_regular.typeface.json', function ( font ) {
const textGeo = new TextGeometry( _text, {
font: font,
size: _scale*3,
height: _scale/10,
curveSegments: 4,
bevelEnabled: true,
bevelThickness: _scale/8,
bevelSize: _scale/10,
bevelOffset: 0,
bevelSegments: 1
} );
textGeo.computeBoundingBox();
//const centerOffset = - 0.5 * ( textGeo.boundingBox.max.x - textGeo.boundingBox.min.x );
textMesh = new THREE.Mesh( textGeo, materials );
textMesh.rotation.z = Math.PI;
textMesh.rotation.y = Math.PI;
textMesh.position.set(_point.x, _point.y, _point.z);
textMesh.renderOrder = 1;
scene.add( textMesh );
} );
}
function selectObjectHierarchy (_id) {
let search = true;
for (let i = 0; i < selectedObjects.length && search === true; i++ ) {
@ -342,7 +387,7 @@ function setupObject (_object, _camera, _light, _data, _controls) {
if (typeof (_data) !== "undefined") {
_object.position.set (_data["objPosition"][0], _data["objPosition"][1], _data["objPosition"][2]);
_object.scale.set (_data["objScale"][0], _data["objScale"][1], _data["objScale"][2]);
_object.rotation.set (THREE.Math.degToRad(_data["objRotation"][0]), THREE.Math.degToRad(_data["objRotation"][1]), THREE.Math.degToRad(_data["objRotation"][2]));
_object.rotation.set (THREE.MathUtils.degToRad(_data["objRotation"][0]), THREE.MathUtils.degToRad(_data["objRotation"][1]), THREE.MathUtils.degToRad(_data["objRotation"][2]));
_object.needsUpdate = true;
if (typeof (_object.geometry) !== "undefined") {
_object.geometry.computeBoundingBox();
@ -374,6 +419,11 @@ function setupObject (_object, _camera, _light, _data, _controls) {
}
}
function render() {
controls.update();
renderer.render( scene, camera );
}
function setupClippingPlanes (_geometry, _size, _distance) {
clippingPlanes[ 0 ].constant = _distance.x;
clippingPlanes[ 1 ].constant = _distance.y;
@ -388,6 +438,7 @@ function setupClippingPlanes (_geometry, _size, _distance) {
distanceGeometry = _distance;
clippingFolder.add( planeParams.planeX, 'displayHelperX' ).onChange( (v) => { planeHelpers[ 0 ].visible = v; renderer.localClippingEnabled = v; } );
clippingFolder.add( planeParams.planeX, 'constant' ).min( - distanceGeometry.x ).max( distanceGeometry.x ).setValue(distanceGeometry.x).step(_size/100).listen().onChange(function (value) {
renderer.localClippingEnabled = true;
clippingPlanes[ 0 ].constant = value;
render();
});
@ -395,6 +446,7 @@ function setupClippingPlanes (_geometry, _size, _distance) {
clippingFolder.add( planeParams.planeY, 'displayHelperY' ).onChange( (v) => { planeHelpers[ 1 ].visible = v; renderer.localClippingEnabled = v; } );
clippingFolder.add( planeParams.planeY, 'constant' ).min( - distanceGeometry.y ).max( distanceGeometry.y ).setValue(distanceGeometry.y).step(_size/100).listen().onChange(function (value) {
renderer.localClippingEnabled = true;
clippingPlanes[ 1 ].constant = value;
render();
});
@ -402,6 +454,7 @@ function setupClippingPlanes (_geometry, _size, _distance) {
clippingFolder.add( planeParams.planeZ, 'displayHelperZ' ).onChange( (v) => { planeHelpers[ 2 ].visible = v; renderer.localClippingEnabled = v; } );
clippingFolder.add( planeParams.planeZ, 'constant' ).min( - distanceGeometry.z ).max( distanceGeometry.z ).setValue(distanceGeometry.z).step(_size/100).listen().onChange(function (value) {
renderer.localClippingEnabled = true;
clippingPlanes[ 2 ].constant = value;
render();
});
@ -565,6 +618,7 @@ function buildGallery() {
document.addEventListener('click', function(event) {
if (!modalGallery.contains(event.target) && !imageList.contains(event.target)) {
//event.preventDefault();
modalGallery.style.display = "none";
zoomImage = 1.0;
modalImage.style.transform = `scale(1.0)`;
@ -574,23 +628,27 @@ function buildGallery() {
modalGallery.appendChild(modalImage);
modalGallery.appendChild(modalClose);
for (var i = 0; imageElements.length - i; imageList.firstChild === imageElements[0] && i++) {
imageElements[i].className += " image-list-item";
imageElements[i].getElementsByTagName("a")[0].setAttribute("href", "#");
imageElements[i].getElementsByTagName("img")[0].onclick = function(){
modalGallery.style.display = "block";
modalImage.src = this.src;
};
//imageElements[i].className += " image-list-item";
var imgList = imageElements[i].getElementsByTagName("a");
for (var j = 0; j < imgList.length; j++) {
imgList[j].setAttribute("href", "#");
imgList[j].setAttribute("src", imgList[j].firstChild.src);
imgList[j].setAttribute("class", "image-list-item");
}
imgList = imageElements[i].getElementsByTagName("img");
for (var j = 0; j < imgList.length; j++) {
imgList[j].onclick = function(){
modalGallery.style.display = "block";
modalImage.src = this.src;
};
}
//imageElements[i].getElementsByTagName("a")[0].setAttribute("href", "#");
imageList.appendChild(imageElements[i]);
}
fileElement[0].insertAdjacentElement('beforebegin', modalGallery);
mainElement.insertBefore(imageList, fileElement[0]);
}
function render() {
controls.update();
renderer.render( scene, camera );
}
function setupCamera (_object, _camera, _light, _data, _controls) {
if (typeof (_data) != "undefined") {
if (typeof (_data["cameraPosition"]) != "undefined") {
@ -638,13 +696,69 @@ function setupCamera (_object, _camera, _light, _data, _controls) {
}
}
function distanceBetweenPoints(pointA, pointB) {
return Math.sqrt(Math.pow(pointB.x - pointA.x, 2) + Math.pow(pointB.y - pointA.y, 2) + Math.pow(pointB.z - pointA.z, 2) ,2);
}
function distanceBetweenPointsVector(vector) {
return Math.sqrt(Math.pow(vector.x, 2) + Math.pow(vector.y, 2) + Math.pow(vector.z, 2) ,2);
}
function vectorBetweenPoints (pointA, pointB) {
return new THREE.Vector3(pointB.x - pointA.x, pointB.y - pointA.y, pointB.z - pointA.z);
}
function halfwayBetweenPoints(pointA, pointB) {
return new THREE.Vector3((pointB.x + pointA.x)/2, (pointB.y + pointA.y)/2, (pointB.z + pointA.z)/2);
}
function interpolateDistanceBetweenPoints(pointA, vector, length, scalar) {
var _x = pointA.x + (scalar/Math.abs(length)) * vector.x;
var _y = pointA.y + (scalar/Math.abs(length)) * vector.y;
var _z = pointA.z + (scalar/Math.abs(length)) * vector.z;
return new THREE.Vector3(_x, _y, _z);
}
function pickFaces(_id) {
var sphere = new THREE.Mesh(new THREE.SphereGeometry(0.1, 7, 7), new THREE.MeshNormalMaterial({
var rulerObject = new THREE.Object3D();
var sphere = new THREE.Mesh(new THREE.SphereGeometry(gridSize/150, 7, 7), new THREE.MeshNormalMaterial({
transparent : true,
opacity : 0.8
opacity : 0.8,
side: THREE.DoubleSide, depthTest: false, depthWrite: false
}));
sphere.position.set(_id[0].point.x, _id[0].point.y, _id[0].point.z);
scene.add(sphere);
var newPoint = new THREE.Vector3( _id[0].point.x, _id[0].point.y, _id[0].point.z );
sphere.position.set( newPoint.x, newPoint.y, newPoint.z );
rulerObject.add(sphere);
linePoints.push( newPoint );
const lineGeometry = new THREE.BufferGeometry().setFromPoints( linePoints );
const line = new THREE.Line( lineGeometry, lineMaterial );
rulerObject.add( line );
var lineMtr = new THREE.LineBasicMaterial({ color: 0x0000FF, linewidth: 3, opacity: 1, side: THREE.DoubleSide, depthTest: false, depthWrite: false });
if (linePoints.length > 1) {
var vectorPoints = vectorBetweenPoints(linePoints[linePoints.length-2], newPoint);
var distancePoints = distanceBetweenPointsVector(vectorPoints);
//var distancePoints = distanceBetweenPoints(linePoints[linePoints.length-2], newPoint);
var halfwayPoints = halfwayBetweenPoints(linePoints[linePoints.length-2], newPoint);
addTextPoint(distancePoints.toFixed(2), gridSize/200, halfwayPoints);
var rulerI = 0;
var measureSize = gridSize/400;
while (rulerI <= distancePoints*100) {
const geoSegm = [];
var interpolatePoints = interpolateDistanceBetweenPoints(linePoints[linePoints.length-2], vectorPoints, distancePoints, rulerI/100);
geoSegm.push(new THREE.Vector3(interpolatePoints.x, interpolatePoints.y, interpolatePoints.z));
//geoSegm.push(new THREE.Vector3(interpolatePoints.x+_id[0].face.normal.x, interpolatePoints.y+_id[0].face.normal.y, interpolatePoints.z+_id[0].face.normal.z));
geoSegm.push(new THREE.Vector3(interpolatePoints.x+measureSize, interpolatePoints.y+measureSize, interpolatePoints.z+measureSize));
const geometryLine = new THREE.BufferGeometry().setFromPoints( geoSegm );
var lineSegm = new THREE.Line(geometryLine, lineMtr);
rulerObject.add(lineSegm);
//var textSprite = makeTextSprite((i * 10).toString(), {r: 255, g: 255, b: 255, a: 255}, new THREE.Vector3(0.2, ruler, 3), Math.PI);
//ruler.add(textSprite);
rulerI+=10;
}
}
rulerObject.renderOrder = 1;
scene.add(rulerObject);
/*if (mainObject.name == "Scene" || mainObject.children.length > 0)
mainObject.traverse( function ( child ) {
if (child.isMesh) {
@ -657,17 +771,33 @@ function pickFaces(_id) {
}
function onWindowResize() {
if (FULLSCREEN)
var rightOffsetDownload = -74;
var rightOffsetEntity = -77;
var rightOffsetFullscreen = 1;
if (FULLSCREEN) {
canvasDimensions = {x: screen.width, y: screen.height};
else
canvasDimensions = {x: window.innerWidth*0.65, y: window.innerHeight*0.55};
rightOffsetDownload = -80.5;
rightOffsetEntity = -83.5;
rightOffsetFullscreen = 1;
}
else {
canvasDimensions = {x: window.self.innerWidth*0.8, y: window.self.innerHeight};
}
container.setAttribute("width", canvasDimensions.x);
container.setAttribute("height", canvasDimensions.y);
mainCanvas.setAttribute("width", canvasDimensions.x);
mainCanvas.setAttribute("height", canvasDimensions.y);
mainCanvas.style.width = "100% !imporant";
mainCanvas.style.height = "100% !important";
renderer.setPixelRatio( window.devicePixelRatio );
camera.aspect = canvasDimensions.x / canvasDimensions.y;
camera.updateProjectionMatrix();
renderer.setSize( canvasDimensions.x, canvasDimensions.y );
fullscreenMode.setAttribute('style', 'bottom:' + (-canvasDimensions.y*1.65 + 25) + 'px');
downloadModel.setAttribute('style', 'right: ' + rightOffsetDownload +'%');
viewEntity.setAttribute('style', 'right: ' + rightOffsetEntity +'%');
fullscreenMode.setAttribute('style', 'bottom:' + Math.round(-canvasDimensions.y + 85) + 'px');
controls.update();
render();
}
@ -707,7 +837,7 @@ function addWissKIMetadata(label, value) {
}
break;
default:
_str = ""
_str = "";
break;
}
if (_str == "period") {
@ -745,26 +875,45 @@ function expandMetadata () {
function fullscreen() {
FULLSCREEN=!FULLSCREEN;
var _container = document.getElementById("MainCanvas");
if (_container.requestFullscreen && FULLSCREEN) {
_container.requestFullscreen();
}
else if (_container.webkitRequestFullscreen && FULLSCREEN) { /* Safari */
_container.webkitRequestFullscreen();
//var _container = document.getElementById("MainCanvas");
var _container = container;
if (FULLSCREEN) {
if (_container.requestFullscreen ) {
_container.requestFullscreen();
}
else if (_container.webkitRequestFullscreen) { /* Safari */
_container.webkitRequestFullscreen();
}
else if (_container.msRequestFullscreen) { /* IE11 */
_container.msRequestFullscreen();
}
else if (_container.mozRequestFullScreen) { /* Mozilla */
_container.mozRequestFullScreen();
}
}
else if (_container.msRequestFullscreen && FULLSCREEN) { /* IE11 */
_container.msRequestFullscreen();
}
else if (_container.mozRequestFullScreen && FULLSCREEN) { /* IE11 */
_container.mozRequestFullScreen();
}
else {
document.exitFullscreen();
FULLSCREEN=false;
else
{
if (document.exitFullscreen) {
document.exitFullscreen();
}
else if (document.webkitExitFullscreen) { /* Safari */
document.webkitExitFullscreen();
}
else if (document.msExitFullscreen) { /* IE11 */
document.msExitFullscreen();
}
}
onWindowResize();
}
function exitFullscreenHandler() {
var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement;
var fullscreenElement2 = document.webkitIsFullScreen && document.mozFullScreen && document.msFullscreenElement;
if (!fullscreenElement && typeof(fullscreenElement2 === undefined) && FULLSCREEN) {
fullscreen();
}
}
function fetchSettings ( path, basename, filename, object, camera, light, controls, orgExtension, extension ) {
var metadata = {'vertices': 0, 'faces': 0};
var hierarchy = [];
@ -773,6 +922,7 @@ function fetchSettings ( path, basename, filename, object, camera, light, contro
if (proxyPath) {
metadataUrl = getProxyPath(metadataUrl);
}
fetch(metadataUrl, {cache: "no-cache"})
.then((response) => {
if (response['status'] !== 404) {
@ -794,10 +944,10 @@ function fetchSettings ( path, basename, filename, object, camera, light, contro
metadata['faces'] += fetchMetadata (child, 'faces');
var shortChildName = truncateString(child.name, GUILength);
if (child.name === '') {
tempArray = {["Mesh"]() {selectObjectHierarchy(child.id)}, 'id': child.id};
tempArray = {["Mesh"]() {selectObjectHierarchy(child.id);}, 'id': child.id};
}
else {
tempArray = { [shortChildName]() {selectObjectHierarchy(child.id)}, 'id': child.id};
tempArray = { [shortChildName]() {selectObjectHierarchy(child.id);}, 'id': child.id};
}
hierarchyFolder = hierarchyMain.addFolder(shortChildName).close();
hierarchyFolder.add(tempArray, shortChildName);
@ -806,10 +956,10 @@ function fetchSettings ( path, basename, filename, object, camera, light, contro
if ( children.isMesh && children.name !== child.name) {
var shortChildrenName = truncateString(children.name, GUILength);
if (children.name === '') {
tempArray = {["Mesh"] (){selectObjectHierarchy(children.id)}, 'id': children.id};
tempArray = {["Mesh"] (){selectObjectHierarchy(children.id);}, 'id': children.id};
}
else {
tempArray = { [shortChildrenName] (){selectObjectHierarchy(children.id)}, 'id': children.id};
tempArray = { [shortChildrenName] (){selectObjectHierarchy(children.id);}, 'id': children.id};
}
clippingGeometry.push(children.geometry);
hierarchyFolder.add(tempArray, shortChildrenName);
@ -825,11 +975,11 @@ function fetchSettings ( path, basename, filename, object, camera, light, contro
metadata['vertices'] += fetchMetadata (object, 'vertices');
metadata['faces'] += fetchMetadata (object, 'faces');
if (object.name === '') {
tempArray = {["Mesh"] (){selectObjectHierarchy(object.id)}, 'id': object.id};
tempArray = {["Mesh"] (){selectObjectHierarchy(object.id);}, 'id': object.id};
object.name = object.id;
}
else {
tempArray = {[object.name] (){selectObjectHierarchy(object.id)}, 'id': object.id};
tempArray = {[object.name] (){selectObjectHierarchy(object.id);}, 'id': object.id};
}
//hierarchy.push(tempArray);
clippingGeometry.push(object.geometry);
@ -874,26 +1024,31 @@ function fetchSettings ( path, basename, filename, object, camera, light, contro
metadataContent += metadataContentTech + '</div>';
canvasText.innerHTML = metadataContent;
metadataContainer.appendChild( canvasText );
var downloadModel = document.createElement('div');
downloadModel = document.createElement('div');
downloadModel.setAttribute('id', 'downloadModel');
var viewEntity = document.createElement('div');
viewEntity = document.createElement('div');
viewEntity.setAttribute('id', 'viewEntity');
var c_path = path;
if (compressedFile !== '') { c_path = domain + '/' +uri; }
console.log(domain + uri);
downloadModel.innerHTML = "<a href='" + c_path + filename + "' download><img src='/typo3conf/ext/dlf/Resources/Public/Javascript/3DViewer/img/cloud-arrow-down.svg' alt='download' width=25 height=25 title='Download source file'/></a>";
var cPath = path;
if (compressedFile !== '') { cPath = domain + '/' +uri; }
downloadModel.innerHTML = "<a href='" + cPath + filename + "' download><img src='/typo3conf/ext/dlf/Resources/Public/Javascript/3DViewer/img/cloud-arrow-down.svg' alt='download' width=25 height=25 title='Download source file'/></a>";
viewEntity.innerHTML = "<a href='" + domain + "/wisski/navigate/" + wisskiID + "/view' target='_blank'><img src='/typo3conf/ext/dlf/Resources/Public/Javascript/3DViewer/img/share.svg' alt='View Entity' width=22 height=22 title='View Entity'/></a>";
metadataContainer.appendChild( downloadModel );
metadataContainer.appendChild( viewEntity );
var fullscreenMode = document.createElement('div');
fullscreenMode = document.createElement('div');
fullscreenMode.setAttribute('id', 'fullscreenMode');
fullscreenMode.setAttribute('style', 'bottom:' + Math.round(-canvasDimensions.y * 1.05 + 26) + 'px');
fullscreenMode.setAttribute('style', 'bottom:' + Math.round(-canvasDimensions.y + 85) + 'px');
fullscreenMode.innerHTML = "<img src='/typo3conf/ext/dlf/Resources/Public/Javascript/3DViewer/img/fullscreen.png' alt='Fullscreen' width=20 height=20 title='Fullscreen mode'/>";
metadataContainer.appendChild(fullscreenMode);
//var _container = document.getElementById("MainCanvas");
container.appendChild(metadataContainer);
document.getElementById ("metadata-collapse").addEventListener ("click", expandMetadata, false);
document.getElementById ("fullscreenMode").addEventListener ("click", fullscreen, false);
if (document.addEventListener) {
document.addEventListener('webkitfullscreenchange', exitFullscreenHandler, false);
document.addEventListener('mozfullscreenchange', exitFullscreenHandler, false);
document.addEventListener('fullscreenchange', exitFullscreenHandler, false);
document.addEventListener('MSFullscreenChange', exitFullscreenHandler, false);
}
}
else
console.log("Error during loading metadata content\n");
@ -938,9 +1093,9 @@ function loadModel ( path, basename, filename, extension, orgExtension ) {
if (proxyPath) {
modelPath = getProxyPath(modelPath);
}
switch(extension) {
case 'obj':
case 'OBJ':
const manager = new THREE.LoadingManager();
manager.onLoad = function ( ) { showToast ("OBJ model has been loaded"); };
manager.addHandler( /\.dds$/i, new DDSLoader() );
@ -962,7 +1117,6 @@ function loadModel ( path, basename, filename, extension, orgExtension ) {
break;
case 'fbx':
case 'FBX':
var FBXloader = new FBXLoader();
FBXloader.load( modelPath, function ( object ) {
object.traverse( function ( child ) {
@ -979,7 +1133,6 @@ function loadModel ( path, basename, filename, extension, orgExtension ) {
break;
case 'ply':
case 'PLY':
loader = new PLYLoader();
loader.load( modelPath, function ( geometry ) {
geometry.computeVertexNormals();
@ -995,7 +1148,6 @@ function loadModel ( path, basename, filename, extension, orgExtension ) {
break;
case 'dae':
case 'DAE':
const loadingManager = new THREE.LoadingManager( function () {
scene.add( object );
} );
@ -1010,7 +1162,6 @@ function loadModel ( path, basename, filename, extension, orgExtension ) {
break;
case 'ifc':
case 'IFC':
const ifcLoader = new IFCLoader();
ifcLoader.ifcManager.setWasmPath( '/typo3conf/ext/dlf/Resources/Public/Javascript/3DViewer/js/jsm/loaders/ifc/' );
ifcLoader.load( modelPath, function ( object ) {
@ -1022,7 +1173,6 @@ function loadModel ( path, basename, filename, extension, orgExtension ) {
break;
case 'stl':
case 'STL':
loader = new STLLoader();
loader.load( modelPath, function ( geometry ) {
let meshMaterial = new THREE.MeshPhongMaterial( { color: 0xff5533, specular: 0x111111, shininess: 200 } );
@ -1040,7 +1190,6 @@ function loadModel ( path, basename, filename, extension, orgExtension ) {
break;
case 'xyz':
case 'XYZ':
loader = new XYZLoader();
loader.load( modelPath, function ( geometry ) {
geometry.center();
@ -1055,7 +1204,6 @@ function loadModel ( path, basename, filename, extension, orgExtension ) {
break;
case 'pcd':
case 'PCD':
loader = new PCDLoader();
loader.load( modelPath, function ( mesh ) {
scene.add( mesh );
@ -1065,9 +1213,9 @@ function loadModel ( path, basename, filename, extension, orgExtension ) {
break;
case 'json':
case 'JSON':
loader = new THREE.ObjectLoader();
loader.load( modelPath, function ( object ) {
loader.load(
modelPath, function ( object ) {
object.position.set (0, 0, 0);
scene.add( object );
fetchSettings (path.replace("gltf/", ""), basename, filename, object, camera, lightObjects[0], controls, orgExtension, extension );
@ -1076,14 +1224,13 @@ function loadModel ( path, basename, filename, extension, orgExtension ) {
break;
case '3ds':
case '3DS':
loader = new TDSLoader( );
loader.setResourcePath( path );
modelPath = path + basename + "." + extension;
if (proxyPath) {
modelPath = getProxyPath(modelPath);
}
loader.load( modelPath, function ( object ) {
loader.load( modelPath + basename + "." + extension, function ( object ) {
object.traverse( function ( child ) {
if ( child.isMesh ) {
//child.material.specular.setScalar( 0.1 );
@ -1097,39 +1244,34 @@ function loadModel ( path, basename, filename, extension, orgExtension ) {
break;
case 'zip':
case 'ZIP':
case 'rar':
case 'RAR':
case 'tar':
case 'TAR':
case 'gz':
case 'GZ':
case 'xz':
case 'XZ':
showToast("Model is being loaded from compressed archive.");
break;
case 'glb':
case 'GLB':
case 'gltf':
case 'GLTF':
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath( '/typo3conf/ext/dlf/Resources/Public/Javascript/3DViewer/js/libs/draco/' );
dracoLoader.preload();
const gltf = new GLTFLoader();
gltf.setDRACOLoader(dracoLoader);
showToast("Trying to load model from " + extension + " representation.");
modelPath = path + basename + "." + extension;
if (proxyPath) {
modelPath = getProxyPath(modelPath);
}
gltf.load(modelPath, function(gltf) {
gltf.scene.traverse( function ( child ) {
if ( child.isMesh ) {
child.castShadow = true;
child.receiveShadow = true;
child.geometry.computeVertexNormals();
if(child.material.map) { child.material.map.anisotropy = 16 };
if(child.material.map) { child.material.map.anisotropy = 16; };
child.material.side = THREE.DoubleSide;
child.material.clippingPlanes = clippingPlanes;
child.material.clipIntersection = false;
@ -1142,6 +1284,7 @@ function loadModel ( path, basename, filename, extension, orgExtension ) {
function ( xhr ) {
var percentComplete = xhr.loaded / xhr.total * 100;
if (percentComplete !== Infinity) {
circle.show();
circle.set(percentComplete, 100);
if (percentComplete >= 100) {
circle.hide();
@ -1150,10 +1293,28 @@ function loadModel ( path, basename, filename, extension, orgExtension ) {
}
},
function ( ) {
showToast("GLTF representation not found, trying original file " + path.replace("gltf/", "") + filename + " [" + orgExtension + "]");
allowedFormats.forEach(function(item, index, array) {
if (EXIT_CODE != 0) { loadModel(path.replace("gltf/", ""), basename, filename, item, orgExtension); }
});
showToast("GLTF or file with given name (possible archive/filename mismatch) representation not found, trying original file [semi-automatic]...");
showToast(path.replace("gltf/", "") + filename + " [" + orgExtension + "]");
var autoBasename = basename.replace(/_[0-9]+$/, '');
if (EXIT_CODE != 0) {
loadModel (path, autoBasename, '', 'glb', orgExtension);
if (EXIT_CODE != 0) {
allowedFormats.forEach(function(item, index, array) {
if (EXIT_CODE != 0) {
loadModel (path.replace("gltf/", ""), autoBasename, filename, item, orgExtension);
}
});
}
}
if (EXIT_CODE != 0) {
allowedFormats.forEach(function(item, index, array) {
if (EXIT_CODE != 0) {
circle.show();
loadModel (path.replace("gltf/", ""), basename, filename, item, orgExtension);
}
});
}
//loadModel(path.replace("gltf/", ""), basename, filename, orgExtension, orgExtension);
imported = true;
}
@ -1180,7 +1341,7 @@ function animate() {
if ( mixer ) mixer.update( delta ); {
TWEEN.update();
}
for ( let i = 0; i < clippingPlanes.length && clippingMode; i ++ ) {
/*for ( let i = 0; i < clippingPlanes.length && clippingMode; i ++ ) {
const plane = clippingPlanes[ i ];
const po = planeObjects[ i ];
if (po !== undefined ) {
@ -1191,7 +1352,7 @@ function animate() {
po.position.z - plane.normal.z,
);
}
}
}*/
if (textMesh !== undefined) { textMesh.lookAt(camera.position); }
renderer.render( scene, camera );
stats.update();
@ -1203,29 +1364,41 @@ function updateObject () {
function onPointerDown( e ) {
//onDownPosition.x = event.clientX;
//onDownPosition.y = event.clientY;
onDownPosition.x = ( e.clientX / canvasDimensions.x ) * 2 - 1;
onDownPosition.y = - ( e.clientY / canvasDimensions.y ) * 2 + 1;
if (e.button == 0) {
onDownPosition.x = ((e.clientX - container.getBoundingClientRect().left)/ renderer.domElement.clientWidth) * 2 - 1;
onDownPosition.y = - ((e.clientY - container.getBoundingClientRect().top) / renderer.domElement.clientHeight) * 2 + 1;
}
}
function onPointerUp( e ) {
onUpPosition.x = ( e.clientX / canvasDimensions.x ) * 2 - 1;
onUpPosition.y = -( e.clientY / canvasDimensions.y ) * 2 + 1;
var mouseVector = new THREE.Vector2();
//onUpPosition.x = ((e.clientX - container.offsetLeft) / canvasDimensions.x) * 2 - 1;
//onUpPosition.y = - ((e.clientY - (container.offsetTop - document.body.scrollTop + 11)) / (canvasDimensions.y)) * 2 + 1;
raycaster.setFromCamera( pointer, camera );
var intersects;
if (EDITOR) {
if (mainObject.name === "Scene" || mainObject.length > 1) {
/*for (let ii = 0; ii < mainObject.length; ii++) {
intersects = raycaster.intersectObjects( mainObject[ii].children, false );
}*/
intersects = raycaster.intersectObjects( mainObject[0].children, false );
//onUpPosition.x = ( e.clientX / canvasDimensions.x ) * 2 - 1;
//onUpPosition.y = -( e.clientY / canvasDimensions.y ) * 2 + 1;
//onUpPosition.x = ( e.clientX / (canvasDimensions.x - container.offsetLeft)) * 2 - 1;
//onUpPosition.y = -( e.clientY / (canvasDimensions.y - container.offsetTop)) * 2 + 1;
if (e.button == 0) {
onUpPosition.x = ((e.clientX - container.getBoundingClientRect().left)/ renderer.domElement.clientWidth) * 2 - 1;
onUpPosition.y = - ((e.clientY - container.getBoundingClientRect().top) / renderer.domElement.clientHeight) * 2 + 1;
if (onUpPosition.x == onDownPosition.x && onUpPosition.y == onDownPosition.y) {
raycaster.setFromCamera( onUpPosition, camera );
var intersects;
if (EDITOR) {
if (mainObject.length > 1) {
for (let ii = 0; ii < mainObject.length; ii++) {
intersects = raycaster.intersectObjects( mainObject[ii].children, true );
}
if (intersects.length <= 0) {
intersects = raycaster.intersectObjects( mainObject, true );
}
}
else {
intersects = raycaster.intersectObjects( mainObject[0], true );
}
if (intersects.length > 0) {
pickFaces(intersects);
}
}
}
else {
intersects = raycaster.intersectObjects( mainObject[0], false );
}
if (intersects.length > 0) {pickFaces(intersects); }
}
}
@ -1242,6 +1415,7 @@ function onPointerMove( event ) {
var intersects = raycaster.intersectObjects( helperObjects[0].children, false );
else
var intersects = raycaster.intersectObjects( helperObjects[0], false );
if ( intersects.length > 0 ) {
const object = intersects[ 0 ].object;
if ( object !== transformControl.object ) {
@ -1310,7 +1484,7 @@ function changeLightRotation () {
function init() {
// model
//canvasDimensions = {x: container.getBoundingClientRect().width, y: container.getBoundingClientRect().bottom};
canvasDimensions = {x: window.self.innerWidth*0.65, y: window.self.innerHeight*0.55};
canvasDimensions = {x: window.self.innerWidth*0.8, y: window.self.innerHeight};
container.setAttribute("width", canvasDimensions.x);
container.setAttribute("height", canvasDimensions.y);
@ -1349,14 +1523,17 @@ function init() {
renderer.setClearColor( 0x263238 );
renderer.domElement.id = 'MainCanvas';
container.appendChild( renderer.domElement );
mainCanvas = document.getElementById("MainCanvas");
canvasText = document.createElement('div');
canvasText.id = "TextCanvas";
canvasText.width = canvasDimensions.x;
canvasText.height = canvasDimensions.y;
//DRUPAL WissKI [start]
//buildGallery();
if (!proxyPath) {
buildGallery();
}
//DRUPAL WissKI [end]
controls = new OrbitControls( camera, renderer.domElement );
@ -1364,13 +1541,13 @@ function init() {
controls.update();
transformControl = new TransformControls( camera, renderer.domElement );
transformControl.rotationSnap = THREE.Math.degToRad(5);
transformControl.addEventListener( 'objectChange', changeScale );
transformControl.space = "local";
transformControl.addEventListener( 'change', render );
transformControl.addEventListener( 'objectChange', changeScale );
transformControl.addEventListener( 'mouseUp', calculateObjectScale );
transformControl.addEventListener( 'dragging-changed', function ( event ) {
controls.enabled = ! event.value
controls.enabled = ! event.value;
} );
scene.add( transformControl );
@ -1393,30 +1570,32 @@ function init() {
scene.add( transformControlLightTarget );
/*try {
} catch (e) {
// statements to handle any exceptions
loadModel(path, basename, filename, extension);
}*/
if (extension === "glb" || extension === "GLB" || extension === "gltf" || extension === "GLTF") {
var _ext = extension.toLowerCase();
if (_ext === "glb" || _ext === "gltf") {
loadModel (path, basename, filename, extension, extension);
}
else if (extension === "zip" || extension === "ZIP" ) {
else if (_ext === "zip" ) {
compressedFile = "_ZIP/";
loadModel (path+basename+compressedFile+"gltf/", basename, filename, "glb", extension);
}
else if (extension === "rar" || extension === "RAR" ) {
else if (_ext === "rar" ) {
compressedFile = "_RAR/";
loadModel (path+basename+compressedFile+"gltf/", basename, filename, "glb", extension);
}
else if (extension === "tar" ) {
else if (_ext === "tar" ) {
compressedFile = "_TAR/";
loadModel (path+basename+compressedFile+"gltf/", basename, filename, "glb", extension);
}
else if (extension === "xz" ) {
else if (_ext === "xz" ) {
compressedFile = "_XZ/";
loadModel (path+basename+compressedFile+"gltf/", basename, filename, "glb", extension);
}
else if (extension === "gz" ) {
else if (_ext === "gz" ) {
compressedFile = "_GZ/";
loadModel (path+basename+compressedFile+"gltf/", basename, filename, "glb", extension);
}
@ -1431,7 +1610,7 @@ function init() {
// stats
stats = new Stats();
stats.domElement.style.cssText = 'position:relative;top:0px;left:0px;max-height:120px;max-width:90px;z-index:2;';
stats.domElement.style.cssText = 'position:relative;top:0px;left:-80px;max-height:120px;max-width:90px;z-index:2;';
container.appendChild( stats.dom );
windowHalfX = canvasDimensions.x / 2;
@ -1441,7 +1620,8 @@ function init() {
editorFolder.add(transformText, 'Transform 3D Object', { None: '', Move: 'translate', Rotate: 'rotate', Scale: 'scale' } ).onChange(function (value)
{
if (value === '') { transformControl.detach(); }
else {
else {
renderer.localClippingEnabled = false;
transformControl.mode = value;
transformControl.attach( helperObjects[0] );
}
@ -1495,7 +1675,7 @@ function init() {
xhr.open(method, jsonRequestURL, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var params;
var rotateMetadata = new THREE.Vector3(THREE.Math.radToDeg(helperObjects[0].rotation.x),THREE.Math.radToDeg(helperObjects[0].rotation.y),THREE.Math.radToDeg(helperObjects[0].rotation.z));
var rotateMetadata = new THREE.Vector3(THREE.MathUtils.radToDeg(helperObjects[0].rotation.x),THREE.MathUtils.radToDeg(helperObjects[0].rotation.y),THREE.MathUtils.radToDeg(helperObjects[0].rotation.z));
var newMetadata = ({"objPosition": [ helperObjects[0].position.x, helperObjects[0].position.y, helperObjects[0].position.z ], "objScale": [ helperObjects[0].scale.x, helperObjects[0].scale.y, helperObjects[0].scale.z ], "objRotation": [ rotateMetadata.x, rotateMetadata.y, rotateMetadata.z ] });
if (saveProperties.Camera) { newMetadata = Object.assign(newMetadata, {"cameraPosition": [ camera.position.x, camera.position.y, camera.position.z ], "controlsTarget": [ controls.target.x, controls.target.y, controls.target.z ]}); }
if (saveProperties.Light) { newMetadata = Object.assign(newMetadata, {"lightPosition": [ dirLight.position.x, dirLight.position.y, dirLight.position.z ], "lightTarget": [ dirLight.rotation._x, dirLight.rotation._y, dirLight.rotation._z ], "lightColor": [ "#" + (dirLight.color.getHexString()).toUpperCase() ], "lightIntensity": [ dirLight.intensity ], "lightAmbientColor": [ "#" + (ambientLight.color.getHexString()).toUpperCase() ], "lightAmbientIntensity": [ ambientLight.intensity ] }); }
@ -1512,12 +1692,13 @@ function init() {
};
xhr.send(params);
}}, 'Save');
/*editorFolder.add({["Picking"] (){
editorFolder.add({["Picking"] (){
EDITOR=!EDITOR;
var _str;
EDITOR ? _str = "enabled" : _str = "disabled";
ruler = new THREE.Group();
showToast ("Face picking is " + _str);
}}, 'Picking');*/
}}, 'Picking');
clippingFolder = editorFolder.addFolder('Clipping Planes').close();
}
}