import * as THREE from "../node_modules/three/build/three.module.js" import { VRButton } from "../node_modules/three/examples/jsm/webxr/VRButton.js"; import { XRControllerModelFactory } from "../node_modules/three/examples/jsm/webxr/XRControllerModelFactory.js"; import { XRHandModelFactory } from "../node_modules/three/examples/jsm/webxr/XRHandModelFactory.js"; import { OrbitControls } from "../node_modules/three/examples/jsm/controls/OrbitControls.js"; import { OculusHandModel } from "../node_modules/three/examples/jsm/webxr/OculusHandModel.js"; import { OculusHandPointerModel } from "../node_modules/three/examples/jsm/webxr/OculusHandPointerModel.js"; import { STLLoader } from "../node_modules/three/examples/jsm/loaders/STLLoader.js"; const scene = new THREE.Scene(); const zHinten = -1.0; const yOben = 0.0; function main() { const renderer = new THREE.WebGLRenderer({canvas: document.querySelector('#c')}); const handModelFactory = new XRHandModelFactory(); const fov = 45; const aspect = window.innerWidth/window.innerHeight; // the canvas default const near = 0.1; const far = 150; const camera = new THREE.PerspectiveCamera(fov, aspect, near, far); camera.position.set(-0.5, 1.0, 1.0); renderer.setSize( window.innerWidth, window.innerHeight ); renderer.setClearColor( 0xffffff ); document.body.appendChild(renderer.domElement ); renderer.xr.enabled = true; document.body.appendChild(VRButton.createButton(renderer)); var controls = new OrbitControls(camera, renderer.domElement); const color = 0xFFFFFF; const intensity = 1.1; const light = new THREE.DirectionalLight(color, intensity); light.position.set(-1, 2, 4); scene.add(light); const ambient = new THREE.AmbientLight(0xffffff, 0.5); scene.add(ambient); const hemi = new THREE.HemisphereLight(0xfffffb, 0x444444, 0.18); hemi.position.set(0, 10, 0); scene.add(hemi); const geometry = new THREE.BoxGeometry(0.05, 0.05, 0.05); const material = new THREE.MeshPhongMaterial({color:0x44aa88}); const cube = new THREE.Mesh(geometry, material); scene.add(cube); cube.position.set(-0.5,0,zHinten); const axesHelper = new THREE.AxesHelper(2); axesHelper.position.set(0,0,zHinten); scene.add( axesHelper ); // Hands if(typeof renderer !== "undefined"){ const controllerModelFactory = new XRControllerModelFactory(); // Hand 0 = Links const controllerGripL = renderer.xr.getControllerGrip( 0 ); controllerGripL.add( controllerModelFactory.createControllerModel( controllerGripL ) ); scene.add( controllerGripL ); const handL = renderer.xr.getHand( 0 ); handL.addEventListener( 'pinchend', () => { //scaling.active = false; var p = handR.joints[ 'thumb-tip' ].position; //socket.send("Info: L x="+p.x+" y="+(p.y-yOben)+" z="+p.z); } ); handL.add( handModelFactory.createHandModel( handL ) ); scene.add( handL ); // Hand 1 = Rechts const controllerGripR = renderer.xr.getControllerGrip( 1 ); controllerGripR.add( controllerModelFactory.createControllerModel( controllerGripR ) ); scene.add( controllerGripR ); const handR = renderer.xr.getHand( 1 ); handR.addEventListener( 'pinchend', () => { //scaling.active = false; var p = handR.joints[ 'thumb-tip' ].position; //socket.send("Info: R x="+p.x+" y="+(p.y-yOben)+" z="+p.z); socket.send("Info: Raum x="+(p.x*1000)+" y="+(-1.0*p.z*1000)+" z="+((p.y-yOben)*1000)); robot.x = -(p.x*1000); robot.y = (1.0*(p.z-zHinten)*1000); robot.z = ((p.y-yOben)*1000); robot.processAndShow(); } ); handR.add( handModelFactory.createHandModel( handR ) ); scene.add( handR ); } function resizeRendererToDisplaySize(renderer) { const canvas = renderer.domElement; const width = canvas.clientWidth; const height = canvas.clientHeight; const needResize = canvas.width !== width || canvas.height !== height; if (needResize) { renderer.setSize(width, height, false); } return needResize; } function render(time) { time *= 0.001; if (resizeRendererToDisplaySize(renderer)) { const canvas = renderer.domElement; camera.aspect = canvas.clientWidth / canvas.clientHeight; camera.updateProjectionMatrix(); } const speed = 1 + .1; const rot = time * speed; cube.rotation.x = rot; cube.rotation.y = rot; renderer.render(scene, camera); } renderer.setAnimationLoop(render); } main(); var bauteile = []; function show3D(r){ if(bauteile.length == 0){ // Weißes, leicht transluzentes PLA-ähnliches Material var matPLA = new THREE.MeshPhysicalMaterial({ color: 0xffffff, metalness: 0.0, roughness: 0.55, transmission: 0.05, opacity: 0.98, transparent: true, clearcoat: 0.0 }); // Holz Anfnag // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv const holz = new THREE.ShaderMaterial({ uniforms: { ringWidth: { value: 0.006 }, // Abstand der Ringe seed: { value: 42.0 }, grainScale: { value: 180.0 }, // Skaliert die feine Maserung ringJitter: { value: 0.45 }, // wie stark die Ringpositionen variieren thicknessMin: { value: 0.028 }, // minimale Ringdicke thicknessMax: { value: 0.065 }, // maximale Ringdicke rayIntensity: { value: 0.14 }, // Stärke der „Holzstrahlen“ warble: { value: 0.008 } // Verzerrung der Ringe (welliger Effekt) }, vertexShader: ` varying vec3 vW; void main() { vec4 wp = modelMatrix * vec4(position,1.0); vW = wp.xyz; gl_Position = projectionMatrix * viewMatrix * wp; } `, fragmentShader: ` varying vec3 vW; uniform float ringWidth; uniform float seed; uniform float grainScale; uniform float ringJitter; uniform float thicknessMin; uniform float thicknessMax; uniform float rayIntensity; uniform float warble; float hash(vec3 p) { return fract(sin(dot(p + seed, vec3(127.1,311.7,74.7))) * 43758.5453); } float noise(vec3 p) { vec3 i = floor(p); vec3 f = fract(p); f = f*f*(3.0-2.0*f); float a = hash(i); float b = hash(i+vec3(1.0,0.0,0.0)); float c = hash(i+vec3(0.0,1.0,0.0)); float d = hash(i+vec3(1.0,1.0,0.0)); float e = hash(i+vec3(0.0,0.0,1.0)); float f1 = hash(i+vec3(1.0,0.0,1.0)); float g = hash(i+vec3(0.0,1.0,1.0)); float h = hash(i+vec3(1.0,1.0,1.0)); return mix(mix(mix(a,b,f.x), mix(c,d,f.x), f.y), mix(mix(e,f1,f.x), mix(g,h,f.x), f.y), f.z); } float fbm(vec3 p){ float v = 0.0; float amp = 0.5; for(int i=0;i<5;i++){ v += amp * noise(p); p *= 2.0; amp *= 0.5; } return v; } void main() { vec2 center = vec2(-0.3, 0.0); vec2 pos = vW.xz - center; float r = length(pos); float ang = atan(pos.y, pos.x); float warp = fbm(vec3(vW.x*3.0, vW.y*1.0, vW.z*3.0)) * warble; r += warp; float base = r / ringWidth; float jitter = fbm(vec3(vW.x*1.2, vW.y*0.5, vW.z*1.2)) * ringJitter; float ringsVal = fract(base + jitter); float tNoise = fbm(vec3(vW.x*12.0, vW.y*6.0, vW.z*12.0)); float thickness = mix(thicknessMin, thicknessMax, tNoise); float d = abs(ringsVal - 0.5); // Ringmask mit stärkerem Kontrast float ringMask = 1.0 - smoothstep(0.0, thickness, d); ringMask = pow(ringMask, 1.5); float grain = fbm(vec3(vW.x * (grainScale * 0.001), vW.y * 0.02, vW.z * (grainScale * 0.001))); grain = grain * 0.5 + 0.5; float raysNoise = fbm(vec3(vW.x*6.0, vW.y*3.0, vW.z*6.0)); float rays = pow(max(0.0, cos(ang * 12.0 + raysNoise * 6.2831)), 16.0) * rayIntensity; // Farben: leicht mehr Kontrast vec3 c1 = vec3(0.85, 0.65, 0.42); // hell vec3 c2 = vec3(0.72, 0.50, 0.32); // mittel vec3 c3 = vec3(0.55, 0.38, 0.20); // dunkel vec3 baseColor = mix(c2, c1, (grain * 0.25 + 0.25)); vec3 color = mix(baseColor, c3, ringMask * 0.75); color *= (1.0 - rays * 0.85); float spots = fbm(vec3(vW.x*30.0, vW.y*6.0, vW.z*30.0)); color += (spots - 0.5) * 0.015; color = clamp(color, 0.0, 1.0); gl_FragColor = vec4(color, 1.0); } ` }); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // Holz Ende var material = new THREE.MeshStandardMaterial( { color: 0x22ee22, roughness: 0.2, metalness: 0.2} ); // 00: BodenBrett, 61mm unter der Achse, 24mm vor der Achse var brettBox = new THREE.BoxGeometry( 0.8, 0.027, 0.078); var brettMesh = new THREE.Mesh( brettBox, holz ); brettMesh.geometry.translate(0,-0.061-0.027/2,-1+0.078/2+0.024); scene.add( brettMesh ); // 0: BasisBox var basisBox = new THREE.BoxGeometry( 0.060, 0.080, 0.080 ); var m2 = new THREE.MeshStandardMaterial({ color: 0xadd8e6, roughness: 0.2, metalness: 0.2}); var basisMesh = new THREE.Mesh( basisBox, material ); basisMesh.castShadow = true; scene.add( basisMesh ); var stlLoader = new STLLoader(); stlLoader.load('/model/Robot7M/1_01_Bodenplatte.stl', function (geometry) { // dunkelblaue, hochglänzende Lack-/Pulverbeschichtung var matO = new THREE.MeshStandardMaterial({ color: 0x0b3d91, metalness: 0.15, roughness: 0.08, clearcoat: 1.0, clearcoatRoughness: 0.02 }); var mesh = new THREE.Mesh( geometry, matO ); mesh.castShadow = true; mesh.rotation.x = Math.PI/2; mesh.rotation.z = 0; mesh.rotation.y = 0; mesh.scale.set(0.001, 0.001, 0.001); mesh.position.x = -63/2000; mesh.position.y = -80/2000;; mesh.position.z = -80/2000;; basisMesh.add(mesh); }); bauteile.push(basisMesh); // 1: Bizeps var oberarmMesh = new THREE.Object3D(); scene.add( oberarmMesh ); bauteile.push(oberarmMesh); stlLoader.load('/model/Robot7M/2_01_Holm_SeitenBlech.stl', function (geometry) { // dunkelblaue, hochglänzende Lack-/Pulverbeschichtung var matO = new THREE.MeshStandardMaterial({ color: 0x0b3d91, metalness: 0.15, roughness: 0.08, clearcoat: 1.0, clearcoatRoughness: 0.02 }); var mesh = new THREE.Mesh( geometry, matO ); mesh.castShadow = true; mesh.rotation.x = -Math.PI/2; mesh.rotation.z = -Math.PI/2; mesh.rotation.y = Math.PI; mesh.scale.set(0.001, 0.001, 0.001); oberarmMesh.add(mesh); }); // Bizeps MotorHalter stlLoader.load('/model/Robot7M/2_02_Bizeps_Motor_Holder.stl', function (geometry) { var mesh = new THREE.Mesh( geometry, matPLA ); mesh.castShadow = true; mesh.rotation.z = Math.PI/2; mesh.rotation.x = Math.PI/2; mesh.scale.set(0.001, 0.001, 0.001); mesh.geometry.translate(275,-57/2,28.5); oberarmMesh.add(mesh); }); // 2: Ellebogen var ellebogenMesh = new THREE.Object3D(); scene.add( ellebogenMesh ); bauteile.push(ellebogenMesh); stlLoader.load('/model/Robot7M/3_01_Ellebogen_Schlank.stl', function (geometry) { var mesh = new THREE.Mesh( geometry, matPLA ); mesh.castShadow = true; mesh.rotation.z = -Math.PI/2; mesh.rotation.x = Math.PI; // lange achse mesh.scale.set(0.001, 0.001, 0.001); // Mesh zentrieren mesh.geometry.translate(0,0,25); ellebogenMesh.add(mesh); }); // 3: Unterarm var unterarmMesh = new THREE.Object3D(); scene.add( unterarmMesh ); bauteile.push(unterarmMesh); stlLoader.load('/model/Robot7M/4_01_Unterarm_Schlank_Rund.stl', function (geometry) { var mesh = new THREE.Mesh( geometry, matPLA ); mesh.castShadow = true; mesh.rotation.x = -Math.PI/2; // lange achse mesh.rotation.z = -Math.PI/2; mesh.scale.set(0.001, 0.001, 0.001); mesh.geometry.translate(0,0,0); unterarmMesh.add(mesh); }); // 4: Handgelenk var handMeshR = new THREE.Object3D(); scene.add( handMeshR ); bauteile.push(handMeshR); stlLoader.load('/model/Robot7M/5_01_Hand_7M_Schlank.stl', function (geometry) { var mesh = new THREE.Mesh( geometry, matPLA ); mesh.castShadow = true; mesh.rotation.x = 0; // -Math.PI/2; // lange achse mesh.rotation.z = 0; //-Math.PI/2; mesh.scale.set(0.001, 0.001, 0.001); mesh.geometry.translate(0,0,0); handMeshR.add(mesh); }); // 5: Hand var handMeshF = new THREE.Object3D(); scene.add( handMeshF ); bauteile.push(handMeshF); stlLoader.load('/model/Robot7M/5_03_Hand_7M_60for50_Fingerhalter.stl', function (geometry) { var mesh = new THREE.Mesh( geometry, matPLA ); mesh.castShadow = true; mesh.rotation.x = 0; mesh.rotation.z = 0; mesh.scale.set(0.001, 0.001, 0.001); mesh.geometry.translate(0,0,0); handMeshF.add(mesh); }); // 6: Finger1 var handMeshFinger = new THREE.Object3D(); scene.add( handMeshFinger ); bauteile.push(handMeshFinger); stlLoader.load('/model/Robot7M/5_05_Finger_Monolith.stl', function (geometry) { var mesh = new THREE.Mesh( geometry, matPLA ); mesh.castShadow = true; mesh.rotation.x = 0; mesh.rotation.z = 0; mesh.scale.set(0.001, 0.001, 0.001); mesh.geometry.translate(-9,-23,0); handMeshFinger.add(mesh); }); // 6: Finger2 var handMeshFinger2 = new THREE.Object3D(); scene.add( handMeshFinger2 ); bauteile.push(handMeshFinger2); stlLoader.load('/model/Robot7M/5_05_Finger_Monolith.stl', function (geometry) { var mesh = new THREE.Mesh( geometry, matPLA ); mesh.castShadow = true; mesh.rotation.x = 0; mesh.rotation.z = 0; mesh.scale.set(0.001, 0.001, 0.001); mesh.geometry.translate(-9,-23,0); handMeshFinger2.add(mesh); }); } bauteile[0].position.x = -robot.xMotor/1000; bauteile[0].position.y = 0; bauteile[0].position.z = 0; // Bizeps bauteile[1].position.y = 28.5/1000; bauteile[1].position.x = -robot.xMotor/1000 + 0.04; bauteile[1].position.z = -25/1000;; bauteile[1].rotation.y = 0; bauteile[1].rotation.x = 0; bauteile[1].applyMatrix4(new THREE.Matrix4().makeRotationX(-robot.alpha)) // Ellebogen bauteile[2].position.x = 0; bauteile[2].position.z = (robot.l2*0.2)/2000; bauteile[2].position.y = 0; bauteile[2].rotation.x = 0; bauteile[2].rotation.y = 0; bauteile[2].rotation.z = 0; bauteile[2].applyMatrix4(new THREE.Matrix4().makeRotationX(-robot.beta)) bauteile[2].position.z += Math.cos(robot.alpha)*robot.l1/1000; bauteile[2].position.y += Math.sin(robot.alpha)*robot.l1/1000; bauteile[2].position.x -= robot.xMotor/1000 - 0.160; // Unterarm bauteile[3].position.x = 0; bauteile[3].position.z = robot.l2/1000; bauteile[3].position.y = 0; bauteile[3].rotation.x = 0; bauteile[3].rotation.y = 0; bauteile[3].rotation.z = 0; bauteile[3].applyMatrix4(new THREE.Matrix4().makeRotationZ(-robot.a + Math.PI)) bauteile[3].applyMatrix4(new THREE.Matrix4().makeRotationX(-robot.beta)) bauteile[3].position.z += Math.cos(robot.alpha)*robot.l1/1000; bauteile[3].position.y += Math.sin(robot.alpha)*robot.l1/1000; bauteile[3].position.x -= robot.xMotor/1000 - 0.160; // Handgelenk bauteile[4].position.x = 0; bauteile[4].position.z = 0; bauteile[4].position.y = 0; bauteile[4].rotation.x = 0; bauteile[4].rotation.y = 0; bauteile[4].rotation.z = 0; bauteile[4].applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI)); // unklar, ob das koorekt ist bauteile[4].applyMatrix4(new THREE.Matrix4().makeRotationX(-robot.b)); bauteile[4].applyMatrix4(new THREE.Matrix4().makeRotationZ(-robot.a+ Math.PI)); bauteile[4].applyMatrix4(new THREE.Matrix4().makeRotationX(-robot.beta)); bauteile[4].position.z += Math.cos(robot.alpha)*robot.l1/1000; bauteile[4].position.y += Math.sin(robot.alpha)*robot.l1/1000; bauteile[4].position.z += Math.cos(robot.beta)*robot.l2/1000; bauteile[4].position.y += Math.sin(robot.beta)*robot.l2/1000; bauteile[4].position.x -= robot.xMotor/1000 - 0.160; // Finger Halter bauteile[5].position.x = -0.057; bauteile[5].position.z = -0.026; bauteile[5].position.y = 0; bauteile[5].rotation.x = 0; bauteile[5].rotation.y = 0; bauteile[5].rotation.z = 0; bauteile[5].applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI)); // unklar, ob das koorekt ist bauteile[5].applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI)); bauteile[5].applyMatrix4(new THREE.Matrix4().makeRotationZ(robot.c)); bauteile[5].applyMatrix4(new THREE.Matrix4().makeRotationX(-robot.b)); bauteile[5].applyMatrix4(new THREE.Matrix4().makeRotationZ(-robot.a+ Math.PI)); bauteile[5].applyMatrix4(new THREE.Matrix4().makeRotationX(-robot.beta)); bauteile[5].position.z += Math.cos(robot.alpha)*robot.l1/1000; bauteile[5].position.y += Math.sin(robot.alpha)*robot.l1/1000; bauteile[5].position.z += Math.cos(robot.beta)*robot.l2/1000; bauteile[5].position.y += Math.sin(robot.beta)*robot.l2/1000; bauteile[5].position.x -= robot.xMotor/1000 - 0.160; // Finger1 bauteile[6].position.x = 0; bauteile[6].position.z = 0; bauteile[6].position.y = 0; bauteile[6].rotation.x = 0; bauteile[6].rotation.y = 0; bauteile[6].rotation.z = 0; bauteile[6].applyMatrix4(new THREE.Matrix4().makeRotationZ(Math.PI/2)); bauteile[6].position.z = 0.026 + 0.009; bauteile[6].position.x += robot.e/1000; bauteile[6].applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI)); // unklar, ob das koorekt ist bauteile[6].applyMatrix4(new THREE.Matrix4().makeRotationZ(robot.c)); bauteile[6].applyMatrix4(new THREE.Matrix4().makeRotationX(-robot.b)); bauteile[6].applyMatrix4(new THREE.Matrix4().makeRotationZ(-robot.a+ Math.PI)); bauteile[6].applyMatrix4(new THREE.Matrix4().makeRotationX(-robot.beta)); bauteile[6].position.z += Math.cos(robot.alpha)*robot.l1/1000; bauteile[6].position.y += Math.sin(robot.alpha)*robot.l1/1000; bauteile[6].position.z += Math.cos(robot.beta)*robot.l2/1000; bauteile[6].position.y += Math.sin(robot.beta)*robot.l2/1000; bauteile[6].position.x -= robot.xMotor/1000 - 0.160; // Finger2 bauteile[7].position.x = 0; bauteile[7].position.z = 0; bauteile[7].position.y = 0; bauteile[7].rotation.x = 0; bauteile[7].rotation.y = 0; bauteile[7].rotation.z = 0; bauteile[7].applyMatrix4(new THREE.Matrix4().makeRotationZ(-Math.PI/2)); bauteile[7].position.z = 0.026 + 0.009; bauteile[7].position.x -= robot.e/1000; bauteile[7].applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI)); // unklar, ob das koorekt ist bauteile[7].applyMatrix4(new THREE.Matrix4().makeRotationZ(robot.c)); bauteile[7].applyMatrix4(new THREE.Matrix4().makeRotationX(-robot.b)); bauteile[7].applyMatrix4(new THREE.Matrix4().makeRotationZ(-robot.a+ Math.PI)); bauteile[7].applyMatrix4(new THREE.Matrix4().makeRotationX(-robot.beta)); bauteile[7].position.z += Math.cos(robot.alpha)*robot.l1/1000; bauteile[7].position.y += Math.sin(robot.alpha)*robot.l1/1000; bauteile[7].position.z += Math.cos(robot.beta)*robot.l2/1000; bauteile[7].position.y += Math.sin(robot.beta)*robot.l2/1000; bauteile[7].position.x -= robot.xMotor/1000 - 0.160; for (var i = 0; i < bauteile.length; i++) { bauteile[i].position.z += zHinten; bauteile[i].position.y += yOben; } } if(!robot.showFunctions.includes(show3D)){ robot.showFunctions.push(show3D); } robot.showRobot();