OpenBuilds-CONTROL/app/js/viewer.js

568 wiersze
15 KiB
JavaScript
Czysty Zwykły widok Historia

2018-08-28 15:09:20 +00:00
// Global Vars
var scene = true;
var camera, renderer;
var projector, mouseVector, containerWidth, containerHeight;
var raycaster = new THREE.Raycaster();
var gridsystem = new THREE.Group();
var container, stats;
var camera, controls, control, scene, renderer, gridsystem, helper;
var clock = new THREE.Clock();
var marker;
var sizexmax;
var sizeymax;
var lineincrement = 50
var camvideo;
var objectsInScene = []; //array that holds all objects we added to the scene.
var clearSceneFlag = false;
2018-08-28 15:29:27 +00:00
var isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
2018-08-28 15:42:31 +00:00
var canvas = !!window.CanvasRenderingContext2D;
2018-08-28 15:29:27 +00:00
2018-08-28 15:09:20 +00:00
// pause Animation when we loose webgl context focus
var pauseAnimation = false;
var size = new THREE.Vector3();
var sky;
var workspace = new THREE.Group();
workspace.name = "Workspace"
var ground;
containerWidth = window.innerWidth;
containerHeight = window.innerHeight;
2019-09-03 18:36:09 +00:00
var animationLoopTimeout;
2018-08-28 15:09:20 +00:00
function drawWorkspace(xmin, xmax, ymin, ymax) {
if (!xmin) xmin = 0;
if (!ymin) ymin = 0;
2019-03-25 19:10:26 +00:00
if (!xmax) xmax = 207
if (!ymax) ymax = 207
2018-08-28 15:09:20 +00:00
var sceneLights = new THREE.Group();
var light = new THREE.DirectionalLight(0xffffff, 0.8);
light.position.set(0, 2, 25).normalize();
light.name = "Light1;"
sceneLights.add(light);
var light2 = new THREE.DirectionalLight(0xffffff);
light2.name = "Light2"
light2.position.set(-500, -500, 1).normalize();
sceneLights.add(light2);
dirLight = new THREE.DirectionalLight(0xffffff, 1);
dirLight.color.setHSL(0.1, 1, 0.95);
dirLight.position.set(-1, 1.75, 1);
dirLight.position.multiplyScalar(30);
dirLight.castShadow = true;
dirLight.shadow.mapSize.width = 2048;
dirLight.shadow.mapSize.height = 2048;
var d = 50;
dirLight.shadow.camera.left = -d;
dirLight.shadow.camera.right = d;
dirLight.shadow.camera.top = d;
dirLight.shadow.camera.bottom = -d;
dirLight.shadow.camera.far = 3500;
dirLight.shadow.bias = -0.0001;
dirLight.name = "dirLight;"
sceneLights.add(dirLight);
hemiLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.6);
hemiLight.color.setHSL(0.6, 1, 0.6);
hemiLight.groundColor.setHSL(0.095, 1, 0.75);
hemiLight.position.set(0, 50, 0);
hemiLight.visible = false;
hemiLight.name = "hemiLight"
sceneLights.add(hemiLight);
// if (helper) {
// workspace.remove(helper);
// }
sceneLights.name = "Scene Lights"
workspace.add(sceneLights);
scene.fog = new THREE.Fog(0xffffff, 1, 20000);
// SKYDOME
2019-10-18 18:55:41 +00:00
if (!disable3Dskybox) {
var uniforms = {
topColor: {
value: new THREE.Color(0x0077ff)
},
bottomColor: {
value: new THREE.Color(0xffffff)
},
offset: {
value: -63
},
exponent: {
value: 0.71
}
};
uniforms.topColor.value.copy(hemiLight.color);
2018-08-28 15:09:20 +00:00
2019-10-18 18:55:41 +00:00
scene.fog.color.copy(uniforms.bottomColor.value);
2018-08-28 15:09:20 +00:00
2019-10-18 18:55:41 +00:00
var vertexShader = document.getElementById('vertexShader').textContent;
var fragmentShader = document.getElementById('fragmentShader').textContent;
2018-08-28 15:09:20 +00:00
2019-10-18 18:55:41 +00:00
var skyGeo = new THREE.SphereGeometry(9900, 64, 15);
var skyMat = new THREE.ShaderMaterial({
vertexShader: vertexShader,
fragmentShader: fragmentShader,
uniforms: uniforms,
side: THREE.DoubleSide
});
2018-08-28 15:09:20 +00:00
2019-10-18 18:55:41 +00:00
sky = new THREE.Mesh(skyGeo, skyMat);
sky.name = "Skydome"
workspace.add(sky);
}
if (!disable3Drealtimepos) {
cone = new THREE.Mesh(new THREE.CylinderGeometry(0, 5, 40, 15, 1, false), new THREE.MeshPhongMaterial({
color: 0x0000ff,
specular: 0x0000ff,
shininess: 00
}));
cone.overdraw = true;
cone.rotation.x = -90 * Math.PI / 180;
cone.position.x = 20;
cone.position.y = 0;
cone.position.z = 0;
cone.material.opacity = 0.6;
cone.material.transparent = true;
cone.castShadow = false;
cone.visible = false;
cone.name = "Simulation Marker"
workspace.add(cone)
}
2018-08-28 15:09:20 +00:00
gridsystem.name = "Grid System"
workspace.add(gridsystem)
2019-09-05 14:58:56 +00:00
redrawGrid(xmin, xmax, ymin, ymax, false);
2018-08-28 15:09:20 +00:00
scene.add(workspace)
}
2018-09-18 14:09:11 +00:00
function redrawGrid(xmin, xmax, ymin, ymax, inches) {
2019-09-13 18:39:59 +00:00
// console.log(xmin, xmax, ymin, ymax, inches)
2018-09-18 14:09:11 +00:00
if (inches) {
xmin = Math.floor(xmin * 25.4);
xmax = Math.ceil(xmax * 25.4);
ymin = Math.floor(ymin * 25.4);
ymax = Math.ceil(ymax * 25.4);
}
2019-09-13 18:39:59 +00:00
// console.log(xmin, xmax, ymin, ymax, inches)
2018-08-28 15:09:20 +00:00
sizexmax = xmax;
sizeymax = ymax;
if (!xmax) {
xmax = 200;
};
if (!ymax) {
ymax = 200;
};
var grid = new THREE.Group();
var axesgrp = new THREE.Object3D();
axesgrp.name = "Axes Markers"
2018-09-18 14:09:11 +00:00
if (inches) {
var unitsval = "in"
2019-09-05 14:58:56 +00:00
var offset = 5 * 2.54
2018-09-18 14:09:11 +00:00
} else {
var unitsval = "mm"
var offset = 5
var size = 5
}
2018-08-28 15:09:20 +00:00
// add axes labels
var xlbl = this.makeSprite(this.scene, "webgl", {
2018-09-18 14:09:11 +00:00
x: parseInt(xmax) + offset,
2018-08-28 15:09:20 +00:00
y: 0,
z: 0,
text: "X",
2018-09-18 14:09:11 +00:00
color: "#ff0000",
size: size
2018-08-28 15:09:20 +00:00
});
var ylbl = this.makeSprite(this.scene, "webgl", {
x: 0,
2018-09-18 14:09:11 +00:00
y: parseInt(ymax) + offset,
2018-08-28 15:09:20 +00:00
z: 0,
text: "Y",
2018-09-18 14:09:11 +00:00
color: "#006600",
size: size
2018-08-28 15:09:20 +00:00
});
2018-09-18 14:09:11 +00:00
2018-08-28 15:09:20 +00:00
axesgrp.add(xlbl);
axesgrp.add(ylbl);
2018-09-18 14:09:11 +00:00
2018-08-28 15:09:20 +00:00
var materialX = new THREE.LineBasicMaterial({
color: 0xcc0000
});
var materialY = new THREE.LineBasicMaterial({
color: 0x00cc00
});
var geometryX = new THREE.Geometry();
geometryX.vertices.push(
new THREE.Vector3(-0.1, 0, 0),
new THREE.Vector3(-0.1, (ymax), 0)
);
var geometryY = new THREE.Geometry();
geometryY.vertices.push(
new THREE.Vector3(0, -0.1, 0),
new THREE.Vector3((xmax), -0.1, 0)
);
var line1 = new THREE.Line(geometryX, materialY);
var line2 = new THREE.Line(geometryY, materialX);
axesgrp.add(line1);
axesgrp.add(line2);
2018-09-18 14:09:11 +00:00
// if (inches) {
// axesgrp.scale.multiplyScalar(2.5);
// }
2018-08-28 15:09:20 +00:00
grid.add(axesgrp);
2018-09-18 14:09:11 +00:00
var step10 = 10;
var step100 = 100;
if (inches) {
2019-09-05 14:58:56 +00:00
step10 = 2.54;
step100 = 25.4;
2018-09-18 14:09:11 +00:00
}
2019-09-05 14:58:56 +00:00
helper = new THREE.GridHelper(xmin, xmax, ymin, ymax, step10, 0x888888);
2018-08-28 15:09:20 +00:00
helper.position.y = 0;
helper.position.x = 0;
helper.position.z = 0;
helper.material.opacity = 0.15;
helper.material.transparent = true;
helper.receiveShadow = false;
helper.name = "GridHelper10mm"
grid.add(helper);
2019-09-05 14:58:56 +00:00
helper = new THREE.GridHelper(xmin, xmax, ymin, ymax, step100, 0x666666);
2018-08-28 15:09:20 +00:00
helper.position.y = 0;
helper.position.x = 0;
helper.position.z = 0;
helper.material.opacity = 0.15;
helper.material.transparent = true;
helper.receiveShadow = false;
helper.name = "GridHelper50mm"
grid.add(helper);
grid.name = "Grid"
2018-09-06 17:50:01 +00:00
gridsystem.children.length = 0
2019-09-05 14:58:56 +00:00
if (inches) {
var ruler = drawRulerInches(xmin, xmax, ymin, ymax, inches)
} else {
var ruler = drawRuler(xmin, xmax, ymin, ymax, inches)
}
2018-08-28 15:09:20 +00:00
gridsystem.add(grid);
2018-09-06 17:50:01 +00:00
gridsystem.add(ruler);
2018-08-28 15:09:20 +00:00
}
function setBullseyePosition(x, y, z) {
//console.log('Set Position: ', x, y, z)
if (x) {
bullseye.position.x = parseInt(x, 10);
};
if (y) {
bullseye.position.y = parseInt(y, 10);
};
if (z) {
bullseye.position.z = (parseInt(z, 10) + 0.1);
};
}
function init3D() {
2019-10-18 18:55:41 +00:00
if (webgl) {
2020-04-17 21:07:39 +00:00
// console.log('WebGL Support found! success: this application will work optimally on this device!');
2019-10-18 18:55:41 +00:00
printLog("<span class='fg-red'>[ 3D Viewer ] </span><span class='fg-green'>WebGL Support found! success: this application will work optimally on this device!</span>")
renderer = new THREE.WebGLRenderer({
autoClearColor: true,
antialias: false,
preserveDrawingBuffer: true
});
// ThreeJS Render/Control/Camera
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 20000);
camera.position.z = 295;
$('#renderArea').append(renderer.domElement);
renderer.setClearColor(0xffffff, 1); // Background color of viewer = transparent
// renderer.setSize(window.innerWidth - 10, window.innerHeight - 10);
renderer.clear();
sceneWidth = document.getElementById("renderArea").offsetWidth,
sceneHeight = document.getElementById("renderArea").offsetHeight;
camera.aspect = sceneWidth / sceneHeight;
renderer.setSize(sceneWidth, sceneHeight)
camera.updateProjectionMatrix();
2019-10-16 13:57:56 +00:00
2019-10-18 18:55:41 +00:00
if (!disable3Dcontrols) {
2019-10-16 13:57:56 +00:00
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.target.set(0, 0, 0); // view direction perpendicular to XY-plane
if (!isMac) {
controls.mouseButtons = {
ORBIT: THREE.MOUSE.MIDDLE,
ZOOM: false,
PAN: THREE.MOUSE.RIGHT
};
}
controls.enableRotate = true;
controls.enableZoom = true; // optional
controls.maxDistance = 8000; // limit max zoom out
controls.enableKeys = false; // Disable Keyboard on canvas
2019-10-18 18:55:41 +00:00
}
2018-08-28 15:09:20 +00:00
2019-10-18 18:55:41 +00:00
drawWorkspace();
2018-08-28 15:09:20 +00:00
2019-10-18 18:55:41 +00:00
// Picking stuff
projector = new THREE.Projector();
mouseVector = new THREE.Vector3();
raycaster.linePrecision = 1
setTimeout(function() {
resetView()
animate();
}, 200)
2018-08-28 15:09:20 +00:00
2018-08-28 15:42:31 +00:00
} else {
2019-10-18 18:55:41 +00:00
console.log('No WebGL Support found on this computer! Disabled 3D Viewer - Sorry!');
printLog('No WebGL Support found on this computer! Disabled 3D Viewer - Sorry!');
2018-08-28 15:16:17 +00:00
$('#gcodeviewertab').hide()
$('#consoletab').click()
2018-08-28 15:16:17 +00:00
return false;
2019-10-18 18:55:41 +00:00
};
2018-08-28 15:09:20 +00:00
}
function animate() {
if (!pauseAnimation) {
camera.updateMatrixWorld();
2020-04-20 20:58:03 +00:00
simAnimate()
2018-08-28 15:09:20 +00:00
if (clearSceneFlag) {
while (scene.children.length > 1) {
scene.remove(scene.children[1])
}
if (object) {
scene.add(object)
2018-08-28 15:09:20 +00:00
}
clearSceneFlag = false;
} // end clearSceneFlag
// Limited FPS https://stackoverflow.com/questions/11285065/limiting-framerate-in-three-js-to-increase-performance-requestanimationframe
2019-09-03 18:36:09 +00:00
animationLoopTimeout = setTimeout(function() {
2018-08-28 15:09:20 +00:00
requestAnimationFrame(animate);
2019-10-16 13:57:56 +00:00
}, 60);
2018-08-28 15:09:20 +00:00
renderer.render(scene, camera);
}
}
2019-10-18 18:55:41 +00:00
function viewExtents(objecttosee) {
if (!disable3Dcontrols) {
// console.log("viewExtents. object:", objecttosee);
// console.log("controls:", controls);
//wakeAnimate();
// lets override the bounding box with a newly
// generated one
// get its bounding box
if (objecttosee) {
// console.log(objecttosee)
var helper = new THREE.BoxHelper(objecttosee);
helper.update();
var box3 = new THREE.Box3();
box3.setFromObject(helper);
var minx = box3.min.x;
var miny = box3.min.y;
var maxx = box3.max.x;
var maxy = box3.max.y;
var minz = box3.min.z;
var maxz = box3.max.z;
2018-08-28 15:09:20 +00:00
2019-10-18 18:55:41 +00:00
controls.reset();
var lenx = maxx - minx;
var leny = maxy - miny;
var lenz = maxz - minz;
var centerx = minx + (lenx / 2);
var centery = miny + (leny / 2);
var centerz = minz + (lenz / 2);
// console.log("lenx:", lenx, "leny:", leny, "lenz:", lenz);
var maxlen = Math.max(lenx, leny, lenz);
var dist = 2 * maxlen;
// center camera on gcode objects center pos, but twice the maxlen
controls.object.position.x = centerx;
controls.object.position.y = centery;
controls.object.position.z = centerz + dist;
controls.target.x = centerx;
controls.target.y = centery;
controls.target.z = centerz;
// console.log("maxlen:", maxlen, "dist:", dist);
var fov = 2.2 * Math.atan(maxlen / (2 * dist)) * (180 / Math.PI);
// console.log("new fov:", fov, " old fov:", controls.object.fov);
if (isNaN(fov)) {
// console.log("giving up on viewing extents because fov could not be calculated");
return;
} else {
// console.log("fov: ", fov);
controls.object.fov = fov;
var L = dist;
var camera2 = controls.object;
var vector = controls.target.clone();
var l = (new THREE.Vector3()).subVectors(camera2.position, vector).length();
var up = camera.up.clone();
var quaternion = new THREE.Quaternion();
// Zoom correction
camera2.translateZ(L - l);
// console.log("up:", up);
up.y = 1;
up.x = 0;
up.z = 0;
quaternion.setFromAxisAngle(up, 0);
camera2.position.applyQuaternion(quaternion);
up.y = 0;
up.x = 1;
up.z = 0;
quaternion.setFromAxisAngle(up, 0);
camera2.position.applyQuaternion(quaternion);
up.y = 0;
up.x = 0;
up.z = 1;
quaternion.setFromAxisAngle(up, 0);
camera2.lookAt(vector);
controls.object.updateProjectionMatrix();
}
2018-08-28 15:09:20 +00:00
}
}
};
function makeSprite(scene, rendererType, vals) {
var canvas = document.createElement('canvas'),
context = canvas.getContext('2d'),
metrics = null,
textHeight = 100,
textWidth = 0,
actualFontSize = 10;
var txt = vals.text;
if (vals.size) actualFontSize = vals.size;
context.font = "normal " + textHeight + "px Impact";
metrics = context.measureText(txt);
var textWidth = metrics.width;
canvas.width = textWidth;
canvas.height = textHeight;
context.font = "normal " + textHeight + "px Impact";
context.textAlign = "center";
context.textBaseline = "middle";
//context.fillStyle = "#ff0000";
context.fillStyle = vals.color;
context.fillText(txt, textWidth / 2, textHeight / 2);
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
texture.minFilter = THREE.LinearFilter;
var material = new THREE.SpriteMaterial({
map: texture,
// useScreenCoordinates: false,
transparent: true,
opacity: 0.6
});
material.transparent = true;
//var textObject = new THREE.Sprite(material);
var textObject = new THREE.Object3D();
textObject.position.x = vals.x;
textObject.position.y = vals.y;
textObject.position.z = vals.z;
var sprite = new THREE.Sprite(material);
textObject.textHeight = actualFontSize;
textObject.textWidth = (textWidth / textHeight) * textObject.textHeight;
if (rendererType == "2d") {
sprite.scale.set(textObject.textWidth / textWidth, textObject.textHeight / textHeight, 1);
} else {
sprite.scale.set(textWidth / textHeight * actualFontSize, actualFontSize, 1);
}
textObject.add(sprite);
//scene.add(textObject);
return textObject;
}
// Global Function to keep three fullscreen
function fixRenderSize() {
if (renderer) {
setTimeout(function() {
sceneWidth = document.getElementById("renderArea").offsetWidth;
sceneHeight = document.getElementById("renderArea").offsetHeight;
renderer.setSize(sceneWidth, sceneHeight);
//renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = sceneWidth / sceneHeight;
camera.updateProjectionMatrix();
2019-10-18 18:55:41 +00:00
if (!disable3Dcontrols) {
controls.reset();
}
2018-08-28 15:09:20 +00:00
setTimeout(function() {
resetView();
}, 10);
}, 10)
2018-08-28 15:09:20 +00:00
}
}
$(window).on('resize', function() {
console.log("Window Resize")
fixRenderSize();
});
function resetView(object) {
2018-09-06 17:50:01 +00:00
// console.log(resetView.caller);
2018-08-28 15:09:20 +00:00
if (!object) {
if (objectsInScene.length > 0) {
var insceneGrp = new THREE.Group()
for (i = 0; i < objectsInScene.length; i++) {
var object = objectsInScene[i].clone();
insceneGrp.add(object)
}
// scene.add(insceneGrp)
viewExtents(insceneGrp);
// scene.remove(insceneGrp)
} else {
viewExtents(helper);
}
} else {
2019-05-01 18:44:44 +00:00
if (object.userData.lines.length > 1) {
viewExtents(object);
}
2018-08-28 15:09:20 +00:00
}
}