|
13 | 13 | <script defer src="/build/pyscript.js"></script>
|
14 | 14 | <link rel="stylesheet" href="/build/pyscript.css" />
|
15 | 15 | <script>
|
16 |
| - var group; |
17 |
| - var container; |
18 |
| - var camera, scene, renderer, obc; |
19 |
| - var positions, colors; |
20 |
| - var particles; |
21 |
| - var pointCloud; |
22 |
| - var particlePositions; |
23 |
| - var linesMesh; |
24 |
| - |
25 |
| - var particlesData = []; |
26 |
| - var maxParticleCount = 1000; |
27 |
| - var particleCount = 500; |
28 |
| - var r = 800; |
29 |
| - var rHalf = r / 2; |
30 |
| - |
31 |
| - var effectController = { |
32 |
| - showDots: true, |
33 |
| - showLines: true, |
34 |
| - minDistance: 150, |
35 |
| - limitConnections: false, |
36 |
| - maxConnections: 20, |
37 |
| - particleCount: 500 |
38 |
| - }; |
39 |
| - |
40 |
| - function init(container, scene, group, camera, helper, segments, positions, colors, pMaterial, particles, particlePositions) { |
41 |
| - particles.setDrawRange( 0, particleCount ); |
42 |
| - particles.setAttribute( 'position', new THREE.BufferAttribute( particlePositions, 3 ).setUsage( THREE.DynamicDrawUsage ) ); |
43 |
| - |
44 |
| - |
45 |
| - pointCloud = new THREE.Points( particles, pMaterial ); |
46 |
| - group.add( pointCloud ); |
47 |
| - |
48 |
| - var geometry = new THREE.BufferGeometry(); |
49 |
| - |
50 |
| - geometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ).setUsage( THREE.DynamicDrawUsage ) ); |
51 |
| - geometry.setAttribute( 'color', new THREE.BufferAttribute( colors, 3 ).setUsage( THREE.DynamicDrawUsage ) ); |
52 |
| - |
53 |
| - geometry.computeBoundingSphere(); |
54 |
| - |
55 |
| - geometry.setDrawRange( 0, 0 ); |
56 |
| - |
57 |
| - var material = new THREE.LineBasicMaterial( { |
58 |
| - vertexColors: true, |
59 |
| - blending: THREE.AdditiveBlending, |
60 |
| - transparent: true |
61 |
| - } ); |
62 |
| - |
63 |
| - linesMesh = new THREE.LineSegments( geometry, material ); |
64 |
| - group.add( linesMesh ); |
65 |
| - |
66 |
| - renderer = new THREE.WebGLRenderer( { antialias: true } ); |
67 |
| - renderer.setPixelRatio( window.devicePixelRatio ); |
68 |
| - renderer.setSize( window.innerWidth, window.innerHeight ); |
69 |
| - renderer.outputEncoding = THREE.sRGBEncoding; |
70 |
| - |
71 |
| - container.appendChild( renderer.domElement ); |
72 |
| - renderer.render( scene, camera ); |
73 |
| - } |
74 |
| - |
75 |
| - function animate() { |
76 |
| - |
77 |
| - let vertexpos = 0; |
78 |
| - let colorpos = 0; |
79 |
| - let numConnected = 0; |
80 |
| - |
81 |
| - for ( let i = 0; i < particleCount; i ++ ) |
82 |
| - particlesData[ i ].numConnections = 0; |
83 |
| - |
84 |
| - for ( let i = 0; i < particleCount; i ++ ) { |
85 |
| - |
86 |
| - var particleData = particlesData[ i ]; |
87 |
| - |
88 |
| - particlePositions[ i * 3 ] += particleData.velocity.x; |
89 |
| - particlePositions[ i * 3 + 1 ] += particleData.velocity.y; |
90 |
| - particlePositions[ i * 3 + 2 ] += particleData.velocity.z; |
91 |
| - |
92 |
| - if ( particlePositions[ i * 3 + 1 ] < - rHalf || particlePositions[ i * 3 + 1 ] > rHalf ) |
93 |
| - particleData.velocity.y = - particleData.velocity.y; |
94 |
| - |
95 |
| - if ( particlePositions[ i * 3 ] < - rHalf || particlePositions[ i * 3 ] > rHalf ) |
96 |
| - particleData.velocity.x = - particleData.velocity.x; |
97 |
| - |
98 |
| - if ( particlePositions[ i * 3 + 2 ] < - rHalf || particlePositions[ i * 3 + 2 ] > rHalf ) |
99 |
| - particleData.velocity.z = - particleData.velocity.z; |
100 |
| - |
101 |
| - if ( effectController.limitConnections && particleData.numConnections >= effectController.maxConnections ) |
102 |
| - continue; |
103 |
| - |
104 |
| - |
105 |
| - for ( let j = i + 1; j < particleCount; j ++ ) { |
106 |
| - |
107 |
| - var particleDataB = particlesData[ j ]; |
108 |
| - if ( effectController.limitConnections && particleDataB.numConnections >= effectController.maxConnections ) |
109 |
| - continue; |
110 |
| - |
111 |
| - var dx = particlePositions[ i * 3 ] - particlePositions[ j * 3 ]; |
112 |
| - var dy = particlePositions[ i * 3 + 1 ] - particlePositions[ j * 3 + 1 ]; |
113 |
| - var dz = particlePositions[ i * 3 + 2 ] - particlePositions[ j * 3 + 2 ]; |
114 |
| - var dist = Math.sqrt( dx * dx + dy * dy + dz * dz ); |
115 |
| - |
116 |
| - if ( dist < effectController.minDistance ) { |
117 |
| - |
118 |
| - particleData.numConnections ++; |
119 |
| - particleDataB.numConnections ++; |
120 |
| - |
121 |
| - var alpha = 1.0 - dist / effectController.minDistance; |
122 |
| - |
123 |
| - positions[ vertexpos ++ ] = particlePositions[ i * 3 ]; |
124 |
| - positions[ vertexpos ++ ] = particlePositions[ i * 3 + 1 ]; |
125 |
| - positions[ vertexpos ++ ] = particlePositions[ i * 3 + 2 ]; |
126 |
| - |
127 |
| - positions[ vertexpos ++ ] = particlePositions[ j * 3 ]; |
128 |
| - positions[ vertexpos ++ ] = particlePositions[ j * 3 + 1 ]; |
129 |
| - positions[ vertexpos ++ ] = particlePositions[ j * 3 + 2 ]; |
130 | 16 |
|
131 |
| - colors[ colorpos ++ ] = alpha; |
132 |
| - colors[ colorpos ++ ] = alpha; |
133 |
| - colors[ colorpos ++ ] = alpha; |
134 |
| - |
135 |
| - colors[ colorpos ++ ] = alpha; |
136 |
| - colors[ colorpos ++ ] = alpha; |
137 |
| - colors[ colorpos ++ ] = alpha; |
138 |
| - |
139 |
| - numConnected ++; |
140 |
| - |
141 |
| - } |
142 |
| - |
143 |
| - } |
144 |
| - |
145 |
| - } |
146 |
| - |
147 |
| - |
148 |
| - linesMesh.geometry.setDrawRange( 0, numConnected * 2 ); |
149 |
| - linesMesh.geometry.attributes.position.needsUpdate = true; |
150 |
| - linesMesh.geometry.attributes.color.needsUpdate = true; |
151 |
| - |
152 |
| - pointCloud.geometry.attributes.position.needsUpdate = true; |
153 |
| - |
154 |
| - render(); |
155 |
| - |
156 |
| - } |
157 |
| - |
158 |
| - function render() { |
159 |
| - |
160 |
| - var time = Date.now() * 0.001; |
161 |
| - |
162 |
| - group.rotation.y = time * 0.5; |
163 |
| - |
164 |
| - |
165 |
| - } |
166 | 17 | </script>
|
167 | 18 | <py-script>
|
168 | 19 | from pyodide import create_proxy, to_js
|
169 | 20 | from js import window
|
170 |
| -from js import Math |
| 21 | +from js import Math, Date |
171 | 22 | from js import THREE
|
172 | 23 | from js import performance
|
173 | 24 | from pyodide import to_js
|
174 | 25 | from js import Object, Float32Array
|
175 |
| -from js import init, animate, render |
176 |
| -from js import group, container, camera, scene, renderer, obc, positions, colors, particles, pointCloud, particlePositions, linesMesh |
177 | 26 |
|
178 | 27 | particlesData = [];
|
179 | 28 | maxParticleCount = 1000;
|
180 | 29 | particleCount = 500;
|
181 | 30 | r = 800;
|
182 | 31 | rHalf = r / 2;
|
183 | 32 |
|
| 33 | +effectController = { |
| 34 | + "showDots": True, |
| 35 | + "showLines": True, |
| 36 | + "minDistance": 150, |
| 37 | + "limitConnections": False, |
| 38 | + "maxConnections": 20, |
| 39 | + "particleCount": 500 |
| 40 | +} |
| 41 | + |
| 42 | +def render(): |
| 43 | + time = Date.now() * 0.001; |
| 44 | + group.rotation.y = time * 0.5; |
| 45 | + |
184 | 46 | container = document.getElementById( 'container' );
|
185 | 47 |
|
186 | 48 | camera = THREE.PerspectiveCamera.new( 45, window.innerWidth / window.innerHeight, 1, 4000 );
|
|
223 | 85 | particlesData.append( {"velocity": THREE.Vector3.new( - 1 + Math.random() * 2, - 1 + Math.random() * 2, - 1 + Math.random() * 2 ), "numConnections": 0} );
|
224 | 86 | i += 1
|
225 | 87 |
|
226 |
| -init(container, scene, group, camera, helper, segments, positions, colors, pMaterial, particles, particlePositions) |
227 |
| -</py-script> |
| 88 | +particles.setDrawRange( 0, particleCount ); |
| 89 | +particles.setAttribute( 'position', THREE.BufferAttribute.new( particlePositions, 3 ).setUsage( THREE.DynamicDrawUsage ) ); |
| 90 | +pointCloud = THREE.Points.new( particles, pMaterial ); |
| 91 | +group.add( pointCloud ); |
| 92 | + |
| 93 | +geometry = THREE.BufferGeometry.new() |
| 94 | + |
| 95 | +geometry.setAttribute( 'position', THREE.BufferAttribute.new( positions, 3 ).setUsage( THREE.DynamicDrawUsage ) ) |
| 96 | +geometry.setAttribute( 'color', THREE.BufferAttribute.new( colors, 3 ).setUsage( THREE.DynamicDrawUsage ) ) |
| 97 | + |
| 98 | +geometry.computeBoundingSphere(); |
| 99 | + |
| 100 | +geometry.setDrawRange( 0, 0 ); |
| 101 | + |
| 102 | +material_perms = {"vertexColors": True,"blending": THREE.AdditiveBlending,"transparent": True} |
| 103 | +material_perms = Object.fromEntries(to_js(material_perms)) |
| 104 | + |
| 105 | +material = THREE.LineBasicMaterial.new(material_perms); |
| 106 | + |
| 107 | +linesMesh = THREE.LineSegments.new( geometry, material ); |
| 108 | +group.add( linesMesh ) |
| 109 | + |
| 110 | +renderer = THREE.WebGLRenderer.new( { "antialias": True } ); |
| 111 | +renderer.setPixelRatio( window.devicePixelRatio ); |
| 112 | +renderer.setSize( window.innerWidth, window.innerHeight ); |
| 113 | +renderer.outputEncoding = THREE.sRGBEncoding; |
| 114 | + |
| 115 | +container.appendChild( renderer.domElement ); |
| 116 | +renderer.render( scene, camera ); |
| 117 | +<!-- |
| 118 | +function animate(effectController) { |
| 119 | +
|
| 120 | + let vertexpos = 0; |
| 121 | + let colorpos = 0; |
| 122 | + let numConnected = 0; |
| 123 | +
|
| 124 | + for ( let i = 0; i < particleCount; i ++ ) |
| 125 | + particlesData[ i ].numConnections = 0; |
| 126 | +
|
| 127 | + for ( let i = 0; i < particleCount; i ++ ) { |
| 128 | +
|
| 129 | + var particleData = particlesData[ i ]; |
| 130 | +
|
| 131 | + particlePositions[ i * 3 ] += particleData.velocity.x; |
| 132 | + particlePositions[ i * 3 + 1 ] += particleData.velocity.y; |
| 133 | + particlePositions[ i * 3 + 2 ] += particleData.velocity.z; |
| 134 | +
|
| 135 | + if ( particlePositions[ i * 3 + 1 ] < - rHalf || particlePositions[ i * 3 + 1 ] > rHalf ) |
| 136 | + particleData.velocity.y = - particleData.velocity.y; |
| 137 | +
|
| 138 | + if ( particlePositions[ i * 3 ] < - rHalf || particlePositions[ i * 3 ] > rHalf ) |
| 139 | + particleData.velocity.x = - particleData.velocity.x; |
| 140 | +
|
| 141 | + if ( particlePositions[ i * 3 + 2 ] < - rHalf || particlePositions[ i * 3 + 2 ] > rHalf ) |
| 142 | + particleData.velocity.z = - particleData.velocity.z; |
| 143 | +
|
| 144 | + if ( effectController.limitConnections && particleData.numConnections >= effectController.maxConnections ) |
| 145 | + continue; |
| 146 | +
|
| 147 | +
|
| 148 | + for ( let j = i + 1; j < particleCount; j ++ ) { |
| 149 | +
|
| 150 | + var particleDataB = particlesData[ j ]; |
| 151 | + if ( effectController.limitConnections && particleDataB.numConnections >= effectController.maxConnections ) |
| 152 | + continue; |
| 153 | +
|
| 154 | + var dx = particlePositions[ i * 3 ] - particlePositions[ j * 3 ]; |
| 155 | + var dy = particlePositions[ i * 3 + 1 ] - particlePositions[ j * 3 + 1 ]; |
| 156 | + var dz = particlePositions[ i * 3 + 2 ] - particlePositions[ j * 3 + 2 ]; |
| 157 | + var dist = Math.sqrt( dx * dx + dy * dy + dz * dz ); |
| 158 | +
|
| 159 | + if ( dist < effectController.minDistance ) { |
| 160 | +
|
| 161 | + particleData.numConnections ++; |
| 162 | + particleDataB.numConnections ++; |
| 163 | +
|
| 164 | + var alpha = 1.0 - dist / effectController.minDistance; |
| 165 | +
|
| 166 | + positions[ vertexpos ++ ] = particlePositions[ i * 3 ]; |
| 167 | + positions[ vertexpos ++ ] = particlePositions[ i * 3 + 1 ]; |
| 168 | + positions[ vertexpos ++ ] = particlePositions[ i * 3 + 2 ]; |
| 169 | +
|
| 170 | + positions[ vertexpos ++ ] = particlePositions[ j * 3 ]; |
| 171 | + positions[ vertexpos ++ ] = particlePositions[ j * 3 + 1 ]; |
| 172 | + positions[ vertexpos ++ ] = particlePositions[ j * 3 + 2 ]; |
| 173 | +
|
| 174 | + colors[ colorpos ++ ] = alpha; |
| 175 | + colors[ colorpos ++ ] = alpha; |
| 176 | + colors[ colorpos ++ ] = alpha; |
| 177 | +
|
| 178 | + colors[ colorpos ++ ] = alpha; |
| 179 | + colors[ colorpos ++ ] = alpha; |
| 180 | + colors[ colorpos ++ ] = alpha; |
| 181 | +
|
| 182 | + numConnected ++; |
| 183 | +
|
| 184 | + } |
| 185 | +
|
| 186 | + } |
| 187 | +
|
| 188 | + } |
| 189 | +
|
| 190 | +
|
| 191 | + linesMesh.geometry.setDrawRange( 0, numConnected * 2 ); |
| 192 | + linesMesh.geometry.attributes.position.needsUpdate = true; |
| 193 | + linesMesh.geometry.attributes.color.needsUpdate = true; |
| 194 | +
|
| 195 | + pointCloud.geometry.attributes.position.needsUpdate = true; |
| 196 | +
|
| 197 | + render(); |
| 198 | +
|
| 199 | +} |
| 200 | +
|
| 201 | +--></py-script> |
228 | 202 | </body>
|
229 | 203 | </html>
|
0 commit comments