]> gitweb.ps.run Git - cloth_sim/blob - Scripts/main.js
render cloth
[cloth_sim] / Scripts / main.js
1 //import {  } from './cloth.js';\r
2 //import { OrbitControls } from './OrbitControls.js';\r
3 \r
4 function addLights(scene){\r
5   scene.add( new THREE.AmbientLight( 0x222222 ) );\r
6 \r
7   const light1 = new THREE.PointLight( 0xffffff, 1, 50 );\r
8   light1.position.set( 15, 1, 40 );\r
9   scene.add( light1 );\r
10 \r
11   const light2 = new THREE.PointLight( 0xffffff, 1, 50 );\r
12   light2.position.set( -15, 0, 40 );\r
13   scene.add( light2 );\r
14 \r
15   const light3 = new THREE.PointLight( 0xffffff, 1, 50 );\r
16   light3.position.set( 0, -1, 40 );\r
17   scene.add( light3 );\r
18 }\r
19 \r
20 /**\r
21  * setup THREE JS Scene, Camera and Renderer\r
22  */\r
23 function setup_scene(canvasSpace) {\r
24   const scene = new THREE.Scene();\r
25   const camera = new THREE.PerspectiveCamera(75, window.innerWidth / (window.innerHeight - canvasSpace), 0.1, 1000);\r
26   const renderer = new THREE.WebGLRenderer();\r
27   /** size canvas to leave some space for UI */\r
28   renderer.setSize(window.innerWidth, window.innerHeight - canvasSpace);\r
29   renderer.antialias = true;\r
30   /** embed canvas in HTML */\r
31   document.getElementById("threejscontainer").appendChild(renderer.domElement);\r
32 \r
33   /** add orbit controls */\r
34   const controls = new THREE.OrbitControls(camera, renderer.domElement);\r
35   controls.target.set(0, 0, 0);\r
36   controls.update();\r
37 \r
38   /** add scene background */\r
39   const loader = new THREE.TextureLoader();\r
40   const texture = loader.load(\r
41     'Textures/tears_of_steel_bridge_2k.jpg',\r
42     () => {\r
43       const rt = new THREE.WebGLCubeRenderTarget(texture.image.height);\r
44       rt.fromEquirectangularTexture(renderer, texture);\r
45       scene.background = rt;\r
46     });\r
47 \r
48   /** add flag pole */\r
49   const geometry = new THREE.CylinderGeometry( 0.02, 0.02, 5, 32 );\r
50   const material = new THREE.MeshStandardMaterial( {color: 0xffffff} );\r
51   const cylinder = new THREE.Mesh( geometry, material );\r
52   cylinder.position.set(-0.5, -2.25, 0);\r
53   scene.add( cylinder );\r
54 \r
55   /** add global light */\r
56   const directionalLight = new THREE.DirectionalLight(0xffffff, 1);\r
57   scene.add(directionalLight);\r
58 \r
59   /** position camera */\r
60   camera.position.z = 2;\r
61   addLights(scene);\r
62   return [scene, camera, renderer];\r
63 }\r
64 \r
65 /** call "init" when document is fully loaded */\r
66 document.body.onload = init;\r
67 \r
68 function init() {\r
69   let mousePos = new THREE.Vector2();\r
70   \r
71   /**\r
72    * Space left empty under canvas\r
73    * for UI elements\r
74    */\r
75   const canvasSpace = 200;\r
76 \r
77   /** Constant Frame Time */\r
78   const frameTime = 1000.0 / 60.0;\r
79 \r
80   /** Setup scene */\r
81   let [scene, camera, renderer] = setup_scene(canvasSpace);\r
82   \r
83   //const loader = new THREE.TextureLoader();\r
84   //Red color: 0xC70039\r
85 \r
86   const cloth = new Cloth(1, 0.5, 20, 10);\r
87   const clothGeometry = cloth.generateGeometry();\r
88   //const clothMaterial = new THREE.MeshStandardMaterial({ map: loader.load('Textures/DeutschlandFlagge.jpg'), color: 0xffffff, side: THREE.DoubleSide, flatShading: false});\r
89   const clothMaterial = new THREE.MeshStandardMaterial({ color: 0xC70039, side: THREE.DoubleSide, flatShading: false });\r
90   const clothMesh = new THREE.Mesh(clothGeometry, clothMaterial);\r
91   scene.add(clothMesh);\r
92   \r
93   let raycaster = new THREE.Raycaster();\r
94   let intersects;\r
95   let rightMousePressed;\r
96   /**\r
97    * function called every frame\r
98    * @param {number} dt - time passed since last frame in ms\r
99    */\r
100   function animate(dt) {\r
101     // simulate cloth\r
102     \r
103     raycaster.setFromCamera( new THREE.Vector2((mousePos.x / w) * 2 - 1, ((h - mousePos.y) / h) * 2 - 1), camera );\r
104 \r
105     // intersects = raycaster.intersectObject( mesh );\r
106 \r
107     // if ( intersects.length > 0 && rightMousePressed) {\r
108     //   // Cloth mouse interaction\r
109     // }\r
110     setTimeout(() => {\r
111       animate(frameTime);\r
112     }, frameTime);\r
113     renderer.render(scene, camera);\r
114   }\r
115 \r
116 \r
117   /** add callback for window resize */\r
118   let canvas = document.getElementsByTagName("canvas")[0];\r
119   let w = window.innerWidth;\r
120   let h = window.innerHeight - canvasSpace;\r
121   let resize = function () {\r
122     w = window.innerWidth;\r
123     h = window.innerHeight - canvasSpace;\r
124     canvas.width = w;\r
125     canvas.height = h;\r
126   }\r
127   window.onresize = resize;\r
128   resize();\r
129 \r
130   /**\r
131    * if canvas has been successfully initialized\r
132    * start rendering\r
133    */\r
134   if (canvas.getContext) {\r
135     animate(performance.now());\r
136   }\r
137 \r
138   \r
139 \r
140   /** add mouse move callback */\r
141   canvas.onmousemove = (evt) => {\r
142     mousePos.x = evt.clientX;\r
143     mousePos.y = evt.clientY;\r
144 \r
145     //cloth.mouseMove(calculateMousePosToWorld(evt));\r
146   };\r
147 \r
148   /**\r
149    * Prevent context menu while blowing wind\r
150    */\r
151   canvas.addEventListener('contextmenu', function(evt) { \r
152     evt.preventDefault();\r
153   }, false);\r
154 \r
155 \r
156   canvas.onmousedown = (evt) => {\r
157 \r
158     // Check mouse click\r
159     rightMousePressed = evt.button == 2;\r
160     \r
161     if(intersects.length > 0 && evt.button == 0){\r
162       //cloth.mousePress(intersects);\r
163     } \r
164   }\r
165   \r
166   canvas.onmouseup = (evt) => {\r
167     //cloth.mouseRelease();\r
168     rightMousePressed = false;\r
169   }\r
170 \r
171   function calculateMousePosToWorld(evt){\r
172     var vec = new THREE.Vector3(); // create once and reuse\r
173     var pos = new THREE.Vector3(); // create once and reuse\r
174 \r
175     vec.set(\r
176       ( evt.clientX / window.innerWidth ) * 2 - 1,\r
177     - ( evt.clientY / window.innerHeight ) * 2 + 1,\r
178       0.5 );\r
179 \r
180     vec.unproject( camera );\r
181 \r
182     vec.sub( camera.position ).normalize();\r
183 \r
184     var distance = - camera.position.z / vec.z;\r
185 \r
186     pos.copy( camera.position ).add( vec.multiplyScalar( distance ) );\r
187     return pos;\r
188   }\r
189 }