Skip to content

Commit bfe7ba1

Browse files
committed
Finished gizmos implementation
1 parent 1664107 commit bfe7ba1

3 files changed

Lines changed: 65 additions & 18 deletions

File tree

src/ui/scene_manager.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ export class SceneManager {
179179
if (e.button !== 0) return;
180180

181181
this.is_dragging = true;
182+
this.last_mx = e.clientX;
183+
this.last_my = e.clientY;
182184

183185
const rect = this.target_element.getBoundingClientRect();
184186
const mouse_x = e.clientX - rect.left;
@@ -188,7 +190,7 @@ export class SceneManager {
188190
const y_ndc = 1.0 - (2.0 * mouse_y) / rect.height;
189191

190192
const view = this.viewport.get_view_matrix();
191-
const projection = this.viewport.get_view_matrix();
193+
const projection = this.viewport.get_projection();
192194
const vp = mul_mat4(projection, view);
193195
const inv_vp = inverse_mat4(vp);
194196

@@ -235,7 +237,12 @@ export class SceneManager {
235237
this.last_my = e.clientY;
236238

237239
if (this.editor_state.mode !== "IDLE") {
238-
this.editor_state.handle_mouse_move(e.clientX, e.clientY);
240+
const view = this.viewport.get_view_matrix();
241+
const projection = this.viewport.get_projection();
242+
const vp = mul_mat4(projection,view);
243+
244+
const {width,height} = this.viewport.get_dimensions();
245+
this.editor_state.handle_mouse_move(e.clientX, e.clientY,vp,width,height);
239246
} else {
240247
this.viewport.orbit(dx, dy);
241248
}

src/ui/state_manager.ts

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { Node } from "../rendering/types/node";
2-
import { vec3 } from "../math/types";
3-
import type { Line } from "../math/types";
2+
import { vec3, vec4 } from "../math/types";
3+
import type { Line, mat4 } from "../math/types";
44
import { Inspector } from "./inspector";
55
import { create_arrow } from "../rendering/utils/primitives";
66
import type { Scene } from "../rendering/types/scene";
77
import { scale } from "../math/transformations";
8+
import { mul_mat4_vec4, scalar_mult_vec3 } from "../math/matrix_operators";
89

910
export type EditorMode = "IDLE" | "TRANSLATE_X" | "TRANSLATE_Y" | "TRANSLATE_Z";
1011

@@ -52,10 +53,16 @@ export class EditorState {
5253
this.inspector.inspect(node);
5354

5455
if (node) {
55-
const scale_amount = node.scale_vec;
56-
this.gizmo_x.scale_vec = scale_amount;
57-
this.gizmo_y.scale_vec = scale_amount;
58-
this.gizmo_z.scale_vec = scale_amount;
56+
let extent = 0
57+
for(let i = 0; i < 3; ++i){
58+
extent = Math.max(node.radius[i] * Math.abs(node.scale_vec[i]),extent);
59+
}
60+
const gizmo_size = extent + 0.2;
61+
62+
63+
this.gizmo_x.scale_vec = vec3(gizmo_size, gizmo_size, gizmo_size);
64+
this.gizmo_y.scale_vec = vec3(gizmo_size, gizmo_size, gizmo_size);
65+
this.gizmo_z.scale_vec = vec3(gizmo_size, gizmo_size, gizmo_size);
5966
this.update_gizmo_transforms();
6067
} else {
6168
this.gizmo_x.scale_vec = vec3(0, 0, 0);
@@ -112,26 +119,45 @@ export class EditorState {
112119
this.select(null);
113120
}
114121

115-
public handle_mouse_move(mouse_x: number, mouse_y: number) {
122+
public handle_mouse_move(mouse_x: number, mouse_y: number, vp: mat4, width: number, height: number) {
116123
if (!this.is_dragging) return;
117124

118125
const dx = mouse_x - this.last_x;
119126
const dy = mouse_y - this.last_y;
120-
121127
this.last_x = mouse_x;
122128
this.last_y = mouse_y;
123129

124130
if (!this.selected_node || this.mode === "IDLE") return;
125131

126-
const sensitivity = 0.02;
132+
const pos = this.selected_node.position;
133+
134+
let axis_3d = vec3(0, 0, 0);
135+
if (this.mode === "TRANSLATE_X") axis_3d = vec3(1, 0, 0);
136+
else if (this.mode === "TRANSLATE_Y") axis_3d = vec3(0, 1, 0);
137+
else if (this.mode === "TRANSLATE_Z") axis_3d = vec3(0, 0, 1);
127138

128-
if (this.mode === "TRANSLATE_X") {
129-
this.selected_node.position[0] += dx * sensitivity;
130-
} else if (this.mode === "TRANSLATE_Y") {
131-
this.selected_node.position[1] -= dy * sensitivity;
132-
} else if (this.mode === "TRANSLATE_Z") {
133-
this.selected_node.position[2] -= (dx + dy) * sensitivity;
139+
const origin_screen = this.project_to_screen(pos, vp, width, height);
140+
141+
const point_on_axis = vec3(pos[0] + axis_3d[0], pos[1] + axis_3d[1], pos[2] + axis_3d[2]);
142+
const axis_screen = this.project_to_screen(point_on_axis, vp, width, height);
143+
144+
let dir_x = axis_screen[0] - origin_screen[0];
145+
let dir_y = axis_screen[1] - origin_screen[1];
146+
147+
const len = Math.sqrt(dir_x * dir_x + dir_y * dir_y);
148+
if (len > 0.0001) {
149+
dir_x /= len;
150+
dir_y /= len;
134151
}
152+
const move_amount = (dx * dir_x) + (dy * dir_y);
153+
154+
const sensitivity = 1 / len;
155+
const total_move = move_amount * sensitivity;
156+
157+
158+
this.selected_node.position[0] += axis_3d[0] * total_move;
159+
this.selected_node.position[1] += axis_3d[1] * total_move;
160+
this.selected_node.position[2] += axis_3d[2] * total_move;
135161

136162
this.selected_node.update_matrix();
137163
this.update_gizmo_transforms();
@@ -148,4 +174,18 @@ export class EditorState {
148174
if (!this.selected_node) return [];
149175
return [this.gizmo_x, this.gizmo_y, this.gizmo_z];
150176
}
177+
178+
private project_to_screen(p:vec3, vp:mat4, width:number, height:number): [number,number]{
179+
const p_clip = mul_mat4_vec4(vp,vec4(p[0],p[1],p[2],1.0));
180+
181+
const ndc_x = p_clip[0] / p_clip[3];
182+
const ndc_y = p_clip[1] / p_clip[3];
183+
184+
185+
const screen_x = (ndc_x + 1.0) * width / 2;
186+
const screen_y = (1.0 - ndc_y) * height / 2;
187+
188+
return [screen_x, screen_y];
189+
190+
}
151191
}

src/utils/parser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function center_geometry(geo: Geometry): void {
2929
}
3030
}
3131

32-
function normalize_geometry(geo:Geometry): void {
32+
export function normalize_geometry(geo:Geometry): void {
3333
let max = -Infinity;
3434
for(let i = 0; i < geo.vertices.length; i+=3){
3535
max = Math.max(max,geo.vertices[i])

0 commit comments

Comments
 (0)