Skip to content

Commit fe629f4

Browse files
committed
scale camera to fit
1 parent 724922c commit fe629f4

File tree

2 files changed

+427
-47
lines changed

2 files changed

+427
-47
lines changed

pyzx/js/zx_viewer3d.js

+38-26
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,14 @@ import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer
2323

2424
export function showGraph3D(tag, graph, width, height, show_labels) {
2525
const scene = new THREE.Scene();
26-
const aspect = height/width;
27-
const scale = 20;
28-
const camera = new THREE.OrthographicCamera(-scale, scale, scale*aspect, -scale*aspect);
2926
const renderer = new THREE.WebGLRenderer({ antialias: true });
3027
const labelRenderer = new CSS2DRenderer();
3128
const light = new THREE.DirectionalLight( 0xffffff, 2);
3229

3330
scene.background = new THREE.Color(0xffffff);
34-
camera.layers.enableAll();
3531
scene.add(new THREE.AmbientLight(0xffffff, 1.5));
3632
light.position.set(1, 1, 1).normalize();
3733
scene.add(light);
38-
camera.position.z = 10;
3934
renderer.setSize(width, height);
4035
labelRenderer.setSize(width, height);
4136
labelRenderer.domElement.style.position = 'absolute';
@@ -61,35 +56,29 @@ export function showGraph3D(tag, graph, width, height, show_labels) {
6156
rightButton.innerHTML = '🡆';
6257
buttons.appendChild(rightButton);
6358

64-
const controls = new OrbitControls( camera, labelRenderer.domElement );
65-
const raycaster = new THREE.Raycaster();
66-
const mouse = new THREE.Vector2();
67-
let highlightRow = -1;
68-
controls.minDistance = 1;
69-
controls.maxDistance = 100;
70-
71-
7259
var ntab = {};
7360

7461
const rows = new Set();
75-
let minY = null, maxY = null, minZ = null, maxZ = null;
62+
let minX = null, maxX = null, minY = null, maxY = null, minZ = null, maxZ = null;
7663

7764
graph.nodes.forEach(function(d) {
7865
ntab[d.name] = d;
7966
d.nhd = [];
8067
rows.add(d.x);
68+
minX = (minX == null) ? d.x : Math.min(d.x, minX);
8169
minY = (minY == null) ? d.y : Math.min(d.y, minY);
8270
minZ = (minZ == null) ? d.z : Math.min(d.z, minZ);
71+
maxX = (maxX == null) ? d.x : Math.max(d.x, maxX);
8372
maxY = (maxY == null) ? d.y : Math.max(d.y, maxY);
8473
maxZ = (maxZ == null) ? d.z : Math.max(d.z, maxZ);
8574

86-
let color = 0x000000, radius = 0.1;
75+
let color = 0x000000, radius = 0.05;
8776
if (d.t == 1) {
8877
color = Number('0x' + '#99dd99'.substring(1));
89-
radius = 0.15;
78+
radius = 0.1;
9079
} else if (d.t == 2) {
9180
color = Number('0x' + '#ff8888'.substring(1));
92-
radius = 0.15;
81+
radius = 0.1;
9382
}
9483

9584
const geometry = new THREE.SphereGeometry(radius, 48, 24);
@@ -98,7 +87,7 @@ export function showGraph3D(tag, graph, width, height, show_labels) {
9887
d.sphere.name = d.name;
9988
d.sphere.position.set(d.x, d.y, d.z);
10089
d.sphere.layers.enableAll();
101-
d.sphere.renderOrder = 0.0;
90+
d.sphere.renderOrder = 0.5;
10291
scene.add(d.sphere);
10392

10493
if (d.phase != '') {
@@ -139,7 +128,7 @@ export function showGraph3D(tag, graph, width, height, show_labels) {
139128
new THREE.Vector3(t.x, t.y, t.z)
140129
]);
141130
d.line = new Line2(geometry, material);
142-
d.line.renderOrder = 0.5;
131+
d.line.renderOrder = 0.6;
143132
scene.add(d.line);
144133
});
145134

@@ -152,24 +141,43 @@ export function showGraph3D(tag, graph, width, height, show_labels) {
152141
highlightPlane.renderOrder = 1.0;
153142
scene.add(highlightPlane);
154143

144+
const aspect = height/width;
145+
let scale = 20;
146+
if (minX != null) {
147+
scale = Math.max((maxX - minX)/2, (maxY-minY)/(2*aspect)) + 2;
148+
}
149+
const camera = new THREE.OrthographicCamera(-scale, scale, scale*aspect, -scale*aspect);
150+
camera.layers.enableAll();
151+
camera.position.z = 5;
152+
if (minX != null) {
153+
camera.position.z = 2*Math.max(maxX, maxY, maxZ);
154+
}
155+
156+
const controls = new OrbitControls(camera, labelRenderer.domElement);
157+
const raycaster = new THREE.Raycaster();
158+
const mouse = new THREE.Vector2();
159+
let highlightRow = -1;
160+
controls.minDistance = 1;
161+
controls.maxDistance = 100;
162+
163+
164+
155165
function checkIntersection() {
156166
raycaster.setFromCamera(mouse, camera);
157167
const intersects = raycaster.intersectObject(scene, true);
158-
if (intersects.length > 0) {
159-
const selectedObject = intersects[0].object;
168+
highlightRow = -1;
169+
for (let obj of intersects) {
170+
const selectedObject = obj.object;
160171
if (Object.hasOwn(selectedObject, 'name') && selectedObject.name != '') {
161172
const d = ntab[selectedObject.name];
162173
highlightRow = rowList.indexOf(d.x);
163-
} else {
164-
highlightRow = -1;
174+
break;
165175
}
166-
} else {
167-
highlightRow = -1;
168176
}
169-
170177
update();
171178
}
172179

180+
173181
function update() {
174182
if (highlightRow == -1) {
175183
highlightPlane.material.opacity = 0.0;
@@ -181,8 +189,10 @@ export function showGraph3D(tag, graph, width, height, show_labels) {
181189
graph.nodes.forEach(function (d) {
182190
if (highlightRow == -1 || rowList[highlightRow] == d.x) {
183191
d.sphere.material.opacity = 1.0;
192+
d.sphere.renderOrder = 0.5;
184193
} else {
185194
d.sphere.material.opacity = 0.4;
195+
d.sphere.renderOrder = 0.7;
186196
}
187197
});
188198

@@ -193,8 +203,10 @@ export function showGraph3D(tag, graph, width, height, show_labels) {
193203
} else {
194204
d.line.material.opacity = 1.0;
195205
}
206+
d.line.renderOrder = 0.6;
196207
} else {
197208
d.line.material.opacity = 0.25;
209+
d.line.renderOrder = 0.8;
198210
}
199211
});
200212
}

0 commit comments

Comments
 (0)