Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I got the following ThreeJS to work somewhat though it might be off in some parts, and the effect perhaps doesn't yet look too convincing, I'm not sure. The distortViaMagnets function is the core of the issue (full running <a href="http://outer-court.com/3d/magnetic.zip" rel="nofollow">HTML and source here</a>; running <a href="http://outer-court.com/3d/magnetic/" rel="nofollow">demo here</a>):</p> <pre><code>'use strict'; var app = null; window.onload = function() { app = new App(); app.init(); } App.prototype.init = function() { this.scene = new THREE.Scene(); this.addCamera(); this.addLights(); this.addSphere(); this.addRenderer(); this.render(); app.animate(); }; App.prototype.distortViaMagnets = function() { var maxMagnets = this.magnets.length, maxVertices = this.sphere.geometry.vertices.length; var magneticMaxValue = this.getDistance3d( {x: 0, y: 0, z: 0}, {x: 1000, y: 1000, z: 1000} ); var strength = 1000, factor = 3; for (var i = 0; i &lt; maxMagnets; i++) { for (var vertexI = 0; vertexI &lt; maxVertices; vertexI++) { var magnet = this.magnets[i]; var vertex = this.sphere.geometry.vertices[vertexI]; var distance = this.getDistance3d(magnet, vertex); var power = magneticMaxValue / distance / strength; vertex.x += ( (magnet.x - vertex.x) * power ) * factor; vertex.y += ( (magnet.y - vertex.y) * power ) * factor; vertex.z += ( (magnet.z - vertex.z) * power ) * factor; } } } App.prototype.animate = function() { app.mainGroup.rotation.y -= .003; requestAnimationFrame(app.animate); app.renderer.render(app.scene, app.camera); }; App.prototype.addCamera = function() { this.camera = new THREE.CombinedCamera(this.width, this.height, 45, 1, 10000); this.camera.position.set(0, 0, 400 - 200); this.camera.lookAt( new THREE.Vector3(0, 0, 0) ); this.scene.add(this.camera); } App.prototype.addSphere = function() { this.mainGroup = new THREE.Object3D(); var radius = 50, segments = 30 * 3, rings = 30 * 3; var geometry = new THREE.SphereGeometry(radius, segments, rings); geometry.dynamic = true; var material = new THREE.MeshPhongMaterial( {color: 0xffffff, opacity: 1} ); this.sphere = new THREE.Mesh(geometry, material); this.sphere.dynamic = true; this.sphere.position.set(0, 0, 0); this.sphere.doubleSided = true; this.addMagnets(); this.distortViaMagnets(); this.mainGroup.add(this.sphere); this.scene.add(this.mainGroup); } App.prototype.addMagnets = function(vertex) { var max = this.sphere.geometry.vertices.length, maxMagnets = 1; for (var i = 1; i &lt;= 2; i++) { var index = Misc.getRandomInt(0, max - 1); var vertex = app.sphere.geometry.vertices[index]; var magnetI = this.magnets.length; this.magnets[magnetI] = this.distortVertex( {x: vertex.x, y: vertex.y, z: vertex.z}, 10 ); this.showMagnet(this.magnets[magnetI]); } var magnetI = 0; this.magnets[magnetI] = {x: 58, y: 0, z: 0}; this.showMagnet(this.magnets[magnetI]); } App.prototype.getDistance3d = function(vertex1, vertex2) { var xfactor = vertex2.x - vertex1.x; var yfactor = vertex2.y - vertex1.y; var zfactor = vertex2.z - vertex1.z; return Math.sqrt( (xfactor*xfactor) + (yfactor*yfactor) + (zfactor*zfactor) ); } App.prototype.showMagnet = function(vertex) { var radius = 1.5, segments = 10, rings = 10; var geometry = new THREE.SphereGeometry(radius, segments, rings); var material = new THREE.MeshPhongMaterial( {color: 0x11ee33, opacity: .6} ); var sphere = new THREE.Mesh(geometry, material); sphere.position.set(vertex.x, vertex.y, vertex.z); this.mainGroup.add(sphere); } App.prototype.distortVertex = function(vertex, distortion) { vertex.x = Misc.distort(vertex.x, distortion); vertex.y = Misc.distort(vertex.y, distortion); vertex.z = Misc.distort(vertex.z, distortion); return vertex; } App.prototype.addRenderer = function() { this.renderer = new THREE.WebGLRenderer( {antialias: true} ); this.renderer.setSize(this.width, this.height); var elmMain = document.getElementById('main'); elmMain.appendChild(this.renderer.domElement); } App.prototype.render = function() { this.renderer.render(this.scene, this.camera); }; App.prototype.addLights = function() { var light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(-50, 250, 250); this.scene.add(light); }; function App() { this.width = window.innerWidth; this.height = window.innerHeight; this.camera = null; this.sphere = null; this.controls = null; this.mainGroup = null; this.renderer = null; this.scene = null; this.magnets = []; this.debugElm = null; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload