import { Face, Spring, Cloth } from './cloth.js'; /** * rendering * Einheiten konsistent * Wind * evtl. an Stoff ziehen */ /** * setup THREE JS Scene, Camera and Renderer */ function setup_scene(canvasSpace) { const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / (window.innerHeight - canvasSpace), 0.1, 1000); const renderer = new THREE.WebGLRenderer(); /** size canvas to leave some space for UI */ renderer.setSize(window.innerWidth, window.innerHeight - canvasSpace); /** embed canvas in HTML */ document.getElementById("threejscontainer").appendChild(renderer.domElement); /** add global light */ const directionalLight = new THREE.DirectionalLight(0xffffff, 1); scene.add(directionalLight); /** position camera */ camera.position.y = 5; camera.position.z = 10; return [scene, camera, renderer]; } /** call "init" when document is fully loaded */ document.body.onload = init; function init() { let mousePos = new THREE.Vector2(); let previousClothSimulation; /** * Space left empty under canvas * for UI elements */ const canvasSpace = 200; /** Constant Frame Time */ const frameTime = 1000.0 / 60.0; /** Setup scene */ let [scene, camera, renderer] = setup_scene(canvasSpace); /** setup cloth and generate debug mesh */ let cloth = new Cloth(); cloth.createBasic(10, 10, 50, 50); //cloth.createDebugMesh(scene); //const material = new THREE.MeshBasicMaterial({ color: 0x0000ff, side: THREE.DoubleSide }); const material = new THREE.MeshStandardMaterial({ color: 0x0000ff, side: THREE.DoubleSide, flatShading: false }); const mesh = new THREE.Mesh(cloth.geometry, material); //const mesh = new THREE.WireframeGeometry(cloth.geometry); //const line = new THREE.LineSegments(mesh); //line.material.depthTest = false; //line.material.opacity = 0.25; //line.material.transparent = true; scene.add(mesh); scene.add( new THREE.AmbientLight( 0x222222 ) ); const light1 = new THREE.PointLight( 0xffffff, 1, 100 ); light1.position.set( 2, 1, 80 ); scene.add( light1 ); const light2 = new THREE.PointLight( 0xffffff, 1, 100 ); light2.position.set( -2, 1, 80 ); scene.add( light2 ); const light3 = new THREE.PointLight( 0xffffff, 1, 100 ); light3.position.set( 0, -1, 80 ); scene.add( light3 ); let raycaster = new THREE.Raycaster(); /** * function called every frame * @param {number} dt - time passed since last frame in ms */ function animate(dt) { cloth.simulate(dt/1000); raycaster.setFromCamera( new THREE.Vector2((mousePos.x / w) * 2 - 1, ((h - mousePos.y) / h) * 2 - 1), camera ); const intersects = raycaster.intersectObject( mesh ); if ( intersects.length > 0 ) { cloth.wind(intersects); } setTimeout(() => { animate(frameTime); }, frameTime); renderer.render(scene, camera); } /** add callback for window resize */ let canvas = document.getElementsByTagName("canvas")[0]; let w = window.innerWidth; let h = window.innerHeight - canvasSpace; let resize = function () { w = window.innerWidth; h = window.innerHeight - canvasSpace; canvas.width = w; canvas.height = h; } window.onresize = resize; resize(); /** * if canvas has been successfully initialized * start rendering */ if (canvas.getContext) { animate(performance.now()); } /** add mouse move callback */ canvas.onmousemove = (evt) => { mousePos.x = evt.clientX; mousePos.y = evt.clientY; }; }