three.js текст из частиц

200
24 августа 2018, 16:10

Создание текста из частиц в three.js с анимацией его появления - вот интересующий меня вопрос.
Какими средствами этого можно добиться? Необходимо ли сначала реализовать это в каком либо 3D редакторе, а потом экспортировать в three, либо же можно сделать штатными средствами библиотеки?
Я новичок в вопросах 3D графики, поэтому прошу совета, ссылки на примеры и статьи.

Answer 1

Можно реализовать в 3D редакторе наверное, а в некоторых несложных случаях можно обойтись и без него. Берем проекцию точки на плоскость xy и смотрим, попадает ли она в проекцию любого из треугольников геометрии на эту же плоскость:

var scene = new THREE.Scene(); 
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000); 
camera.position.set(0, 10, 20); 
var renderer = new THREE.WebGLRenderer({ 
  antialias: true 
}); 
renderer.setSize(window.innerWidth, window.innerHeight); 
document.body.appendChild(renderer.domElement); 
 
var controls = new THREE.OrbitControls(camera, renderer.domElement); 
 
var light = new THREE.DirectionalLight(0xffffff, 2); 
light.position.setScalar(100); 
scene.add(light); 
 
var textGeo = null; 
var newGeo = null; 
var textPoints = null; 
var loader = new THREE.FontLoader(); 
loader.load('https://threejs.org/examples/fonts/droid/droid_serif_bold.typeface.json', function(response) { 
  var font = response; 
  setText(font); 
  render(); 
}); 
 
function setText(font) { 
  textGeo = new THREE.TextGeometry("ABC", { 
    font: font, 
    size: 4, 
    height: 0.25, 
    curveSegments: 1, 
    bevelEnabled: false 
  }); 
  textGeo.computeBoundingBox(); 
  textGeo.computeVertexNormals(); 
  textGeo.center(); 
 
  fillWithPoints(textGeo, 1000); 
 
  textGeo.vertices.forEach(function(vertex) { 
    vertex.startPoint = vertex.clone(); 
    vertex.direction = vertex.clone().normalize(); 
  }) 
  textPoints = new THREE.Points(textGeo, new THREE.PointsMaterial({ 
    color: 0x00ff00, 
    size: 0.1 
  })); 
  scene.add(textPoints); 
} 
 
function fillWithPoints(geometry, pointNumber) { 
  geometry.computeBoundingBox(); 
  for (var i = 0; i < pointNumber; i++) { 
    setRandomPoint(geometry); 
  } 
} 
 
function setRandomPoint(geometry) { 
  var point = new THREE.Vector3( 
    THREE.Math.randFloat(geometry.boundingBox.min.x, geometry.boundingBox.max.x), 
    THREE.Math.randFloat(geometry.boundingBox.min.y, geometry.boundingBox.max.y), 
    THREE.Math.randFloat(geometry.boundingBox.min.z, geometry.boundingBox.max.z) 
  ); 
  //console.log(point); 
  if (isPointInside(point, geometry)) { 
    geometry.vertices.push(point); 
  } else { 
    setRandomPoint(geometry); 
  } 
} 
 
var a = new THREE.Vector3(); 
var b = new THREE.Vector3(); 
var c = new THREE.Vector3(); 
var face = new THREE.Face3(); 
 
function isPointInside(point, geometry) { 
  var retVal = false; 
  for (var i = 0; i < geometry.faces.length; i++) { 
    face = geometry.faces[i]; 
    a = geometry.vertices[face.a]; 
    b = geometry.vertices[face.b]; 
    c = geometry.vertices[face.c]; 
    //console.log(face, a, b, c); 
    if (ptInTriangle(point, a, b, c)) { 
      var retVal = true; 
      break; 
    } 
  } 
  return retVal; 
} 
 
function ptInTriangle(p, p0, p1, p2) { 
  // credits: http://jsfiddle.net/PerroAZUL/zdaY8/1/ 
  var A = 1 / 2 * (-p1.y * p2.x + p0.y * (-p1.x + p2.x) + p0.x * (p1.y - p2.y) + p1.x * p2.y); 
  var sign = A < 0 ? -1 : 1; 
  var s = (p0.y * p2.x - p0.x * p2.y + (p2.y - p0.y) * p.x + (p0.x - p2.x) * p.y) * sign; 
  var t = (p0.x * p1.y - p0.y * p1.x + (p0.y - p1.y) * p.x + (p1.x - p0.x) * p.y) * sign; 
 
  return s > 0 && t > 0 && (s + t) < 2 * A * sign; 
} 
 
 
function render() { 
  requestAnimationFrame(render); 
  textGeo.vertices.forEach(function(vertex) { 
    vertex.copy(vertex.startPoint).addScaledVector(vertex.direction, 5 + Math.sin(Date.now() * 0.001) * 5); 
  }); 
  textGeo.verticesNeedUpdate = true; 
  renderer.render(scene, camera); 
}
body { 
  overflow: hidden; 
  margin: 0 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/94/three.min.js"></script> 
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

READ ALSO
Вопрос по JavaScript и HTML

Вопрос по JavaScript и HTML

Всем приветЯ написал скрипт для сайта он берет параметр из тега p и каждый час вычитает по 1 и вставляет обратно, но при обновлении страницы...

150
403 Forbidden при попытке подключить Yandex Maps

403 Forbidden при попытке подключить Yandex Maps

Столкнулся со следующей проблемой - при попытке подключить Yandex Maps через $('head')append('<script src="https://api-maps

190
Увеличить val и изменить placehlder

Увеличить val и изменить placehlder

Задача: после нажатия на кнопку, value инпута должно попасть в p, одновременно с этим placeholder инпута должен стать value + 100

183
Не добавляет элементы в массив [закрыт]

Не добавляет элементы в массив [закрыт]

Собственно, вот чем я сбит с толку

193