Skip to content

Commit 7b7038f

Browse files
Julien Moreau-Mathisjulien-moreau
authored andcommitted
feat: now animate camera to focused object
#562
1 parent 6a85ad8 commit 7b7038f

File tree

1 file changed

+49
-13
lines changed

1 file changed

+49
-13
lines changed

editor/src/editor/layout/preview.tsx

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from ".
4040
import { Editor } from "../main";
4141

4242
import { isSound } from "../../tools/guards/sound";
43-
import { Tween } from "../../tools/animation/tween";
4443
import { isVector3 } from "../../tools/guards/math";
4544
import { isDomTextInputFocused } from "../../tools/dom";
4645
import { isNodeLocked } from "../../tools/node/metadata";
@@ -49,6 +48,7 @@ import { initializeHavok } from "../../tools/physics/init";
4948
import { isAnyParticleSystem } from "../../tools/guards/particles";
5049
import { onTextureAddedObservable } from "../../tools/observables";
5150
import { waitNextAnimationFrame, waitUntil } from "../../tools/tools";
51+
import { ITweenConfiguration, Tween } from "../../tools/animation/tween";
5252
import { checkProjectCachedCompressedTextures } from "../../tools/ktx/check";
5353
import { createSceneLink, getRootSceneLink } from "../../tools/scene/scene-link";
5454
import { isAbstractMesh, isCamera, isCollisionInstancedMesh, isCollisionMesh, isInstancedMesh, isLight, isMesh, isTransformNode } from "../../tools/guards/nodes";
@@ -329,33 +329,69 @@ export class EditorPreview extends Component<IEditorPreviewProps, IEditorPreview
329329
return;
330330
}
331331

332+
const camera = this.scene.activeCamera;
333+
if (!camera) {
334+
return;
335+
}
336+
337+
let target: Vector3 | undefined;
332338
let position: Vector3 | undefined;
339+
333340
if (isCamera(selectedNode)) {
334-
position = selectedNode.globalPosition;
335-
} else if (isAbstractMesh(selectedNode) || isLight(selectedNode) || isTransformNode(selectedNode)) {
336-
position = selectedNode.getAbsolutePosition();
341+
target = selectedNode.globalPosition;
342+
} else if (isAbstractMesh(selectedNode)) {
343+
selectedNode.refreshBoundingInfo({
344+
applyMorph: true,
345+
applySkeleton: true,
346+
updatePositionsArray: true,
347+
});
348+
349+
const bb = selectedNode.getBoundingInfo();
350+
const center = bb.boundingSphere.centerWorld;
351+
352+
const fov = camera.fov;
353+
const aspect = camera.getEngine().getAspectRatio(camera);
354+
const sizeVec = bb.boundingBox.maximumWorld.subtract(bb.boundingBox.minimumWorld);
355+
356+
const verticalSize = sizeVec.y;
357+
const horizontalSize = sizeVec.x;
358+
359+
const verticalDistance = verticalSize / 2 / Math.tan(fov / 2);
360+
const horizontalDistance = horizontalSize / 2 / Math.tan((fov * aspect) / 2);
361+
const idealDistance = Math.max(verticalDistance, horizontalDistance);
362+
363+
const directionToMesh = camera.globalPosition.subtract(center).normalize();
364+
365+
position = center.add(directionToMesh.scale(idealDistance));
366+
target = bb.boundingBox.centerWorld;
367+
} else if (isLight(selectedNode) || isTransformNode(selectedNode)) {
368+
target = selectedNode.getAbsolutePosition();
337369
} else if (isAnyParticleSystem(selectedNode)) {
338370
if (isAbstractMesh(selectedNode.emitter)) {
339-
position = selectedNode.emitter.getAbsolutePosition();
371+
target = selectedNode.emitter.getAbsolutePosition();
340372
} else if (isVector3(selectedNode.emitter)) {
341-
position = selectedNode.emitter;
373+
target = selectedNode.emitter;
342374
}
343375
} else if (isSound(selectedNode)) {
344376
const soundPosition = selectedNode["_position"] as Vector3;
345377

346378
if (selectedNode["_connectedTransformNode"]) {
347-
position = selectedNode["_connectedTransformNode"].getAbsolutePosition();
379+
target = selectedNode["_connectedTransformNode"].getAbsolutePosition();
348380
} else if (!soundPosition.equalsToFloats(0, 0, 0)) {
349-
position = selectedNode["_position"]();
381+
target = selectedNode["_position"]();
350382
}
351383
}
352384

353-
const camera = this.scene.activeCamera;
385+
if (target) {
386+
const tweenConfiguration = {
387+
target,
388+
} as ITweenConfiguration;
354389

355-
if (position && camera) {
356-
Tween.create(camera, 0.5, {
357-
target: position,
358-
});
390+
if (position) {
391+
tweenConfiguration.position = position;
392+
}
393+
394+
Tween.create(camera, 0.5, tweenConfiguration);
359395
}
360396
}
361397

0 commit comments

Comments
 (0)