kopia lustrzana https://github.com/OpenBuilds/OpenBuilds-CONTROL
568 wiersze
15 KiB
JavaScript
568 wiersze
15 KiB
JavaScript
// 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;
|
|
|
|
var isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
|
|
var canvas = !!window.CanvasRenderingContext2D;
|
|
|
|
// 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;
|
|
|
|
var animationLoopTimeout;
|
|
|
|
function drawWorkspace(xmin, xmax, ymin, ymax) {
|
|
|
|
if (!xmin) xmin = 0;
|
|
if (!ymin) ymin = 0;
|
|
if (!xmax) xmax = 207
|
|
if (!ymax) ymax = 207
|
|
|
|
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
|
|
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);
|
|
|
|
scene.fog.color.copy(uniforms.bottomColor.value);
|
|
|
|
var vertexShader = document.getElementById('vertexShader').textContent;
|
|
var fragmentShader = document.getElementById('fragmentShader').textContent;
|
|
|
|
var skyGeo = new THREE.SphereGeometry(9900, 64, 15);
|
|
var skyMat = new THREE.ShaderMaterial({
|
|
vertexShader: vertexShader,
|
|
fragmentShader: fragmentShader,
|
|
uniforms: uniforms,
|
|
side: THREE.DoubleSide
|
|
});
|
|
|
|
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)
|
|
}
|
|
gridsystem.name = "Grid System"
|
|
workspace.add(gridsystem)
|
|
redrawGrid(xmin, xmax, ymin, ymax, false);
|
|
scene.add(workspace)
|
|
}
|
|
|
|
function redrawGrid(xmin, xmax, ymin, ymax, inches) {
|
|
// console.log(xmin, xmax, ymin, ymax, inches)
|
|
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);
|
|
}
|
|
// console.log(xmin, xmax, ymin, ymax, inches)
|
|
|
|
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"
|
|
|
|
if (inches) {
|
|
var unitsval = "in"
|
|
var offset = 5 * 2.54
|
|
} else {
|
|
var unitsval = "mm"
|
|
var offset = 5
|
|
var size = 5
|
|
}
|
|
|
|
// add axes labels
|
|
var xlbl = this.makeSprite(this.scene, "webgl", {
|
|
x: parseInt(xmax) + offset,
|
|
y: 0,
|
|
z: 0,
|
|
text: "X",
|
|
color: "#ff0000",
|
|
size: size
|
|
});
|
|
var ylbl = this.makeSprite(this.scene, "webgl", {
|
|
x: 0,
|
|
y: parseInt(ymax) + offset,
|
|
z: 0,
|
|
text: "Y",
|
|
color: "#006600",
|
|
size: size
|
|
});
|
|
|
|
|
|
axesgrp.add(xlbl);
|
|
axesgrp.add(ylbl);
|
|
|
|
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);
|
|
|
|
// if (inches) {
|
|
// axesgrp.scale.multiplyScalar(2.5);
|
|
// }
|
|
|
|
grid.add(axesgrp);
|
|
|
|
var step10 = 10;
|
|
var step100 = 100;
|
|
if (inches) {
|
|
step10 = 2.54;
|
|
step100 = 25.4;
|
|
}
|
|
helper = new THREE.GridHelper(xmin, xmax, ymin, ymax, step10, 0x888888);
|
|
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);
|
|
helper = new THREE.GridHelper(xmin, xmax, ymin, ymax, step100, 0x666666);
|
|
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"
|
|
|
|
gridsystem.children.length = 0
|
|
if (inches) {
|
|
var ruler = drawRulerInches(xmin, xmax, ymin, ymax, inches)
|
|
} else {
|
|
var ruler = drawRuler(xmin, xmax, ymin, ymax, inches)
|
|
}
|
|
gridsystem.add(grid);
|
|
gridsystem.add(ruler);
|
|
|
|
}
|
|
|
|
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() {
|
|
|
|
if (webgl) {
|
|
// console.log('WebGL Support found! success: this application will work optimally on this device!');
|
|
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();
|
|
|
|
|
|
if (!disable3Dcontrols) {
|
|
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
|
|
}
|
|
|
|
|
|
|
|
drawWorkspace();
|
|
|
|
// Picking stuff
|
|
projector = new THREE.Projector();
|
|
mouseVector = new THREE.Vector3();
|
|
raycaster.linePrecision = 1
|
|
|
|
setTimeout(function() {
|
|
resetView()
|
|
animate();
|
|
}, 200)
|
|
|
|
} else {
|
|
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!');
|
|
$('#gcodeviewertab').hide()
|
|
$('#consoletab').click()
|
|
return false;
|
|
};
|
|
|
|
}
|
|
|
|
function animate() {
|
|
if (!pauseAnimation) {
|
|
camera.updateMatrixWorld();
|
|
simAnimate()
|
|
if (clearSceneFlag) {
|
|
while (scene.children.length > 1) {
|
|
scene.remove(scene.children[1])
|
|
}
|
|
|
|
if (object) {
|
|
scene.add(object)
|
|
}
|
|
|
|
clearSceneFlag = false;
|
|
} // end clearSceneFlag
|
|
|
|
// Limited FPS https://stackoverflow.com/questions/11285065/limiting-framerate-in-three-js-to-increase-performance-requestanimationframe
|
|
animationLoopTimeout = setTimeout(function() {
|
|
requestAnimationFrame(animate);
|
|
}, 60);
|
|
|
|
renderer.render(scene, camera);
|
|
}
|
|
}
|
|
|
|
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;
|
|
|
|
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
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();
|
|
if (!disable3Dcontrols) {
|
|
controls.reset();
|
|
}
|
|
setTimeout(function() {
|
|
resetView();
|
|
}, 10);
|
|
}, 10)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$(window).on('resize', function() {
|
|
console.log("Window Resize")
|
|
fixRenderSize();
|
|
});
|
|
|
|
function resetView(object) {
|
|
// console.log(resetView.caller);
|
|
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 {
|
|
if (object.userData.lines.length > 1) {
|
|
viewExtents(object);
|
|
}
|
|
}
|
|
} |