javascript - Dibujando una línea con three.js dinámicamente
webgl (3)
Dibuja una linea en tiempo real
Aquí un violín actualizado
donde
optimicé
el código de
user3325025
su ejemplo;
En este caso no hay absolutamente ninguna necesidad de actualizar todos los puntos de la línea en el render.
La actualización solo es necesaria en
onMouseMove
(actualizar el final de línea) y en
onMouseDown
(dibujar un nuevo punto):
// update line
function updateLine() {
positions[count * 3 - 3] = mouse.x;
positions[count * 3 - 2] = mouse.y;
positions[count * 3 - 1] = mouse.z;
line.geometry.attributes.position.needsUpdate = true;
}
// mouse move handler
function onMouseMove(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
mouse.z = 0;
mouse.unproject(camera);
if( count !== 0 ){
updateLine();
}
}
// add point
function addPoint(event){
positions[count * 3 + 0] = mouse.x;
positions[count * 3 + 1] = mouse.y;
positions[count * 3 + 2] = mouse.z;
count++;
line.geometry.setDrawRange(0, count);
updateLine();
}
Esto es lo que me gustaría lograr (un polígono modificable donde los círculos rojos son vértices) y me gustaría construir el polígono dinámicamente.
Al iniciar la geometría como
var geometry = new THREE.Geometry();
geometry.vertices.push(point);
geometry.vertices.push(point);
var line = new THREE.Line(geometry, new THREE.LineBasicMaterial({}));
funciona bien hasta el segundo clic, construye una línea recta entre 1 y 2 pero no agrega una tercera línea cuando se empuja a la matriz. WebGL parece requerir puntos almacenados.
Cuando defino vértices como este, puedo dibujar dos líneas (tercer clic)
var geometry = new THREE.Geometry();
for (var i = 0; i < 4; i++) {
geometry.vertices.push(point);
}
var line = new THREE.Line(geometry, new THREE.LineBasicMaterial({}));
pero esta no es una buena solución ya que no sé cuántos vértices quiere agregar el usuario y no tiene sentido asignarle un gran número, ya que tengo que repetirlo varias veces.
¿Hay alguna manera de evitarlo?
Actualicé el violín con eventos del mouse y una matriz de vectores si quieres garabatear a mano alzada.
https://jsfiddle.net/w67tzfhx/40/
function onMouseDown(evt) {
if(evt.which == 3) return;
var x = ( event.clientX / window.innerWidth ) * 2 - 1;
var y = - ( event.clientY / window.innerHeight ) * 2 + 1;
// do not register if right mouse button is pressed.
var vNow = new THREE.Vector3(x, y, 0);
vNow.unproject(camera);
console.log(vNow.x + " " + vNow.y+ " " + vNow.z);
splineArray.push(vNow);
document.addEventListener("mousemove",onMouseMove,false);
document.addEventListener("mouseup",onMouseUp,false);
}
Puede animar una línea, o aumentar el número de puntos representados, muy fácilmente usando
BufferGeometry
y el método
setDrawRange()
.
Sin embargo, debe establecer un número máximo de puntos.
var MAX_POINTS = 500;
// geometry
var geometry = new THREE.BufferGeometry();
// attributes
var positions = new Float32Array( MAX_POINTS * 3 ); // 3 vertices per point
geometry.addAttribute( ''position'', new THREE.BufferAttribute( positions, 3 ) );
// draw range
drawCount = 2; // draw the first 2 points, only
geometry.setDrawRange( 0, drawCount );
// material
var material = new THREE.LineBasicMaterial( { color: 0xff0000 } );
// line
line = new THREE.Line( geometry, material );
scene.add( line );
Establece los datos de posición usando un patrón como este:
var positions = line.geometry.attributes.position.array;
var x = y = z = index = 0;
for ( var i = 0, l = MAX_POINTS; i < l; i ++ ) {
positions[ index ++ ] = x;
positions[ index ++ ] = y;
positions[ index ++ ] = z;
x += ( Math.random() - 0.5 ) * 30;
y += ( Math.random() - 0.5 ) * 30;
z += ( Math.random() - 0.5 ) * 30;
}
Si desea cambiar el número de puntos renderizados después del primer render, haga esto:
line.geometry.setDrawRange( 0, newValue );
Si desea cambiar los
valores de los datos de posición
después del primer renderizado, establezca el indicador
needsUpdate
la
needsUpdate
manera:
line.geometry.attributes.position.needsUpdate = true; // required after the first render
Aquí hay un violín que muestra una línea animada que puede adaptar a su caso de uso.
EDITAR: vea esta respuesta para una técnica que le guste más, especialmente si la línea consta de solo unos pocos puntos.
three.js r.84