0
我正在試着在three.js中呈現d3力圖,我使用帶有照片紋理的標準Line和BoxGeometry。在力圖表更新我叫畫功能,這也叫上當相機在三個j中移動時線會消失
controls.addEventListener('change',() => {this.redraw()});
,但是當我移動相機,一些線路disapear,當 我更近,似乎最壞的,除了它不看就像有任何規則,即使當我接近圖表時,它看起來像是隨機選擇disapear的線條。
有線是
這是,如果我移動相機有點角度
這是從圖中的一側:
這是當其他:
整個代碼:
import {
WebGLRenderer,
Scene,
PerspectiveCamera,
Texture,
MeshBasicMaterial,
SphereGeometry,
Mesh,
Geometry,
Vector3,
LineBasicMaterial,
Line,
LineSegments,
BoxGeometry,
TextureLoader
} from 'three';
import * as three from 'three';
import { ViewModel, Link, Node } from './Model';
import { event } from 'd3-selection';
import * as selection from 'd3-selection';
import { drag } from 'd3-drag';
// Old module syntax
declare function require(name:String);
let OrbitControls = require('./../../../node_modules/three-orbit-controls/index')(three);
interface IView {
render():void;
}
class ViewNode {
public vector:Vector3;
public mesh:Mesh;
public node:Node;
}
export class Full3DView implements IView {
private canvas: Element;
private renderer: WebGLRenderer;
private scene: Scene;
private lineMaterial: LineBasicMaterial;
private camera: PerspectiveCamera;
private controls: any;
private nodes:ViewNode[] = [];
private lines:Geometry[] = [];
constructor(private model:ViewModel) {
this.canvas = document.querySelector('#view3d2');
this.model.onChange(() => {this.render()});
}
render(): void {
this.buildScene();
this.model.simulation.on('tick',() => this.redraw());
this.model.linkForce.distance(40);
this.model.collideForce.radius(30);
}
private buildScene() {
this.scene = new Scene();
this.camera = new PerspectiveCamera(90, window.innerWidth/window.innerHeight, 1, 20000);
this.renderer = new WebGLRenderer();
this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);
this.canvas.appendChild(this.renderer.domElement);
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
this.controls.addEventListener('change',() => {this.redraw()});
this.lineMaterial = new LineBasicMaterial({ color: 0xccff00, linewidth: 3});
let vectorIndex:Map<String, Vector3> = new Map();
let textureLoader = new TextureLoader();
this.model.nodes.forEach((node:Node) => {
this.buildNode(vectorIndex, textureLoader, node);
});
this.model.links.forEach((link:Link) => {
this.buildEdge(vectorIndex, link);
});
this.camera.position.z = 5000;
}
private buildNode(vectorIndex:Map<String, Vector3>, textureLoader:TextureLoader, node:Node) {
let material = new MeshBasicMaterial();
let geometry = new BoxGeometry(30, 30, 30);
let mesh = new Mesh(geometry, material);
mesh.lookAt(this.camera.position);
this.scene.add(mesh);
mesh.position.set(node.x, node.y, 0);
mesh.rotation.x += 1;
vectorIndex.set(node.index, mesh.position);
this.nodes.push({
vector: mesh.position,
mesh: mesh,
node: node
});
textureLoader.load('/data/images/' + node.id + '.jpg', (texture:Texture) => {
material.map = texture;
material.needsUpdate = true;
});
}
private buildEdge(vectorIndex:Map<String, Vector3>, link:Link) {
let geometry = new Geometry();
geometry.vertices.push(
vectorIndex.get(link.source.index).copy(vectorIndex.get(link.source.index).setZ(0)),
vectorIndex.get(link.target.index).copy(vectorIndex.get(link.target.index).setZ(0))
);
geometry.computeLineDistances();
this.lines.push(geometry);
let line = new Line(geometry, this.lineMaterial);
this.scene.add(line);
}
private redraw() {
this.nodes.forEach((node:ViewNode) => {
node.vector.setX(node.node.x * 10);
node.vector.setY(node.node.y * 10);
node.mesh.lookAt(this.camera.position);
node.mesh.frustumCulled = false;
});
this.lines.forEach((line:Geometry) => {
line.verticesNeedUpdate = true;
});
this.renderer.render(this.scene, this.camera)
}
}
(1)在一個單一的繪圖調用呈現所有段顯然是一種改進。 (2)對於你的問題可能的解釋是,當你更新幾何的頂點時,你應該調用'geometry.computeBoundingSphere()'。渲染器會在第一次渲染調用中爲您調用它,但在此之後,如果修改了頂點,則邊界球不再正確,您需要更新它。或者,您可以設置'mesh.frustumCulled = false'; – WestLangley