|
@@ -2,22 +2,41 @@
|
|
|
import * as THREE from "../../../libs/three.js/build/three.module.js";
|
|
|
import { EventDispatcher } from "../../EventDispatcher.js";
|
|
|
import { Utils } from "../../utils.js";
|
|
|
-import {Line2} from "../../../libs/three.js/lines/Line2.js";
|
|
|
-import {LineGeometry} from "../../../libs/three.js/lines/LineGeometry.js";
|
|
|
-import {LineMaterial} from "../../../libs/three.js/lines/LineMaterial.js";
|
|
|
+
|
|
|
+import {LineDraw} from "../../utils/DrawUtil";
|
|
|
+import CurveCtrl from "../../objects/tool/CurveCtrl";
|
|
|
+
|
|
|
|
|
|
+
|
|
|
|
|
|
-class ControlPoint{
|
|
|
-
|
|
|
- constructor(){
|
|
|
- this.position = new THREE.Vector3(0, 0, 0);
|
|
|
- this.target = new THREE.Vector3(0, 0, 0);
|
|
|
- this.positionHandle = null;
|
|
|
- this.targetHandle = null;
|
|
|
- }
|
|
|
-
|
|
|
-};
|
|
|
+const colors = {
|
|
|
+ position: 'red',
|
|
|
+ target : 'blue'
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+let lineMats
|
|
|
+const getLineMat = function(name){
|
|
|
+ if(!lineMats){
|
|
|
+ lineMats = {
|
|
|
+ position: LineDraw.createFatLineMat({
|
|
|
+ color: colors.position,
|
|
|
+ lineWidth: 3
|
|
|
+ }),
|
|
|
+ target : LineDraw.createFatLineMat({
|
|
|
+ color: colors.target,
|
|
|
+ lineWidth: 3
|
|
|
+ }),
|
|
|
+ frustum: LineDraw.createFatLineMat({
|
|
|
+ color: colors.position,
|
|
|
+ lineWidth: 2
|
|
|
+ }),
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return lineMats[name]
|
|
|
+}
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
|
export class CameraAnimation extends EventDispatcher{
|
|
@@ -29,7 +48,7 @@ export class CameraAnimation extends EventDispatcher{
|
|
|
|
|
|
this.selectedElement = null;
|
|
|
|
|
|
- this.controlPoints = [];
|
|
|
+ //this.controlPoints = [];
|
|
|
|
|
|
this.uuid = THREE.Math.generateUUID();
|
|
|
|
|
@@ -47,8 +66,19 @@ export class CameraAnimation extends EventDispatcher{
|
|
|
this.curveType = "centripetal"
|
|
|
this.visible = true;
|
|
|
|
|
|
- this.createUpdateHook();
|
|
|
+
|
|
|
this.createPath();
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ this.addEventListener('dispose', ()=>{
|
|
|
+
|
|
|
+ this.dispose()
|
|
|
+ })
|
|
|
+
|
|
|
}
|
|
|
|
|
|
static defaultFromView(viewer){
|
|
@@ -69,7 +99,7 @@ export class CameraAnimation extends EventDispatcher{
|
|
|
0.05 * camera.position.z + 0.95 * target.z,
|
|
|
);
|
|
|
|
|
|
- const r = camera.position.distanceTo(target) * 0.3;
|
|
|
+ const r = 2//camera.position.distanceTo(target) * 0.3;
|
|
|
|
|
|
//const dir = target.clone().sub(camera.position).normalize();
|
|
|
const angle = Utils.computeAzimuth(camera.position, target);
|
|
@@ -93,180 +123,78 @@ export class CameraAnimation extends EventDispatcher{
|
|
|
targetCenter.z,
|
|
|
];
|
|
|
|
|
|
- const cp = animation.createControlPoint();
|
|
|
- cp.position.set(...cpPos);
|
|
|
- cp.target.set(...targetPos);
|
|
|
+ animation.createControlPoint();
|
|
|
+ animation.posCurve.points[i].fromArray(cpPos)
|
|
|
+ animation.targetCurve.points[i].fromArray(targetPos)
|
|
|
+
|
|
|
}
|
|
|
|
|
|
+ animation.changeCallback()
|
|
|
return animation;
|
|
|
}
|
|
|
|
|
|
- createUpdateHook(){
|
|
|
- const viewer = this.viewer;
|
|
|
-
|
|
|
- viewer.addEventListener("update", () => {
|
|
|
-
|
|
|
- const camera = viewer.scene.getActiveCamera();
|
|
|
- const {width, height} = viewer.renderer.getSize(new THREE.Vector2());
|
|
|
-
|
|
|
- this.node.visible = this.visible;
|
|
|
-
|
|
|
- for(const cp of this.controlPoints){
|
|
|
-
|
|
|
- { // position
|
|
|
- const projected = cp.position.clone().project(camera);
|
|
|
-
|
|
|
- const visible = this.visible && (projected.z < 1 && projected.z > -1);
|
|
|
-
|
|
|
- if(visible){
|
|
|
- const x = width * (projected.x * 0.5 + 0.5);
|
|
|
- const y = height - height * (projected.y * 0.5 + 0.5);
|
|
|
-
|
|
|
- cp.positionHandle.svg.style.left = x - cp.positionHandle.svg.clientWidth / 2;
|
|
|
- cp.positionHandle.svg.style.top = y - cp.positionHandle.svg.clientHeight / 2;
|
|
|
- cp.positionHandle.svg.style.display = "";
|
|
|
- }else{
|
|
|
- cp.positionHandle.svg.style.display = "none";
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- { // target
|
|
|
- const projected = cp.target.clone().project(camera);
|
|
|
-
|
|
|
- const visible = this.visible && (projected.z < 1 && projected.z > -1);
|
|
|
-
|
|
|
- if(visible){
|
|
|
- const x = width * (projected.x * 0.5 + 0.5);
|
|
|
- const y = height - height * (projected.y * 0.5 + 0.5);
|
|
|
-
|
|
|
- cp.targetHandle.svg.style.left = x - cp.targetHandle.svg.clientWidth / 2;
|
|
|
- cp.targetHandle.svg.style.top = y - cp.targetHandle.svg.clientHeight / 2;
|
|
|
- cp.targetHandle.svg.style.display = "";
|
|
|
- }else{
|
|
|
- cp.targetHandle.svg.style.display = "none";
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- this.line.material.resolution.set(width, height);
|
|
|
-
|
|
|
- this.updatePath();
|
|
|
-
|
|
|
- { // frustum
|
|
|
- const frame = this.at(this.t);
|
|
|
- const frustum = this.frustum;
|
|
|
-
|
|
|
- frustum.position.copy(frame.position);
|
|
|
- frustum.lookAt(...frame.target.toArray());
|
|
|
- frustum.scale.set(20, 20, 20);
|
|
|
-
|
|
|
- frustum.material.resolution.set(width, height);
|
|
|
- }
|
|
|
-
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- createControlPoint(index){
|
|
|
+
|
|
|
|
|
|
+ createControlPoint(index){
|
|
|
+ const length = this.posCurve.points.length
|
|
|
+ const position = new THREE.Vector3
|
|
|
+ const target = new THREE.Vector3
|
|
|
+
|
|
|
if(index === undefined){
|
|
|
- index = this.controlPoints.length;
|
|
|
+ index = length;
|
|
|
}
|
|
|
-
|
|
|
- const cp = new ControlPoint();
|
|
|
-
|
|
|
-
|
|
|
- if(this.controlPoints.length >= 2 && index === 0){
|
|
|
- const cp1 = this.controlPoints[0];
|
|
|
- const cp2 = this.controlPoints[1];
|
|
|
-
|
|
|
- const dir = cp1.position.clone().sub(cp2.position).multiplyScalar(0.5);
|
|
|
- cp.position.copy(cp1.position).add(dir);
|
|
|
-
|
|
|
- const tDir = cp1.target.clone().sub(cp2.target).multiplyScalar(0.5);
|
|
|
- cp.target.copy(cp1.target).add(tDir);
|
|
|
- }else if(this.controlPoints.length >= 2 && index === this.controlPoints.length){
|
|
|
- const cp1 = this.controlPoints[this.controlPoints.length - 2];
|
|
|
- const cp2 = this.controlPoints[this.controlPoints.length - 1];
|
|
|
-
|
|
|
- const dir = cp2.position.clone().sub(cp1.position).multiplyScalar(0.5);
|
|
|
- cp.position.copy(cp1.position).add(dir);
|
|
|
-
|
|
|
- const tDir = cp2.target.clone().sub(cp1.target).multiplyScalar(0.5);
|
|
|
- cp.target.copy(cp2.target).add(tDir);
|
|
|
- }else if(this.controlPoints.length >= 2){
|
|
|
- const cp1 = this.controlPoints[index - 1];
|
|
|
- const cp2 = this.controlPoints[index];
|
|
|
-
|
|
|
- cp.position.copy(cp1.position.clone().add(cp2.position).multiplyScalar(0.5));
|
|
|
- cp.target.copy(cp1.target.clone().add(cp2.target).multiplyScalar(0.5));
|
|
|
+
|
|
|
+
|
|
|
+ if(length >= 2 && index === 0){
|
|
|
+ const dir = new THREE.Vector3().subVectors(this.posCurve.points[0], this.posCurve.points[1] )
|
|
|
+ position.copy(this.posCurve.points[0]).add(dir);
|
|
|
+
|
|
|
+ const tDir = new THREE.Vector3().subVectors(this.targetCurve.points[0], this.targetCurve.points[1] )
|
|
|
+ target.copy(this.targetCurve.points[0]).add(dir);
|
|
|
+
|
|
|
+ }else if(length >= 2 && index === length){
|
|
|
+ const dir = new THREE.Vector3().subVectors(this.posCurve.points[length-1], this.posCurve.points[length-2] )
|
|
|
+ position.copy(this.posCurve.points[length-2]).add(dir);
|
|
|
+
|
|
|
+ const tDir = new THREE.Vector3().subVectors(this.targetCurve.points[length-1], this.targetCurve.points[length-2] )
|
|
|
+ target.copy(this.targetCurve.points[length-2]).add(dir);
|
|
|
+
|
|
|
+ }else if(length >= 2){
|
|
|
+ position.copy(this.posCurve.points[index-1].clone().add(this.posCurve.points[index]).multiplyScalar(0.5));
|
|
|
+ target.copy(this.targetCurve.points[index-1].clone().add(this.targetCurve.points[index]).multiplyScalar(0.5));
|
|
|
}
|
|
|
|
|
|
- // cp.position.copy(viewer.scene.view.position);
|
|
|
- // cp.target.copy(viewer.scene.view.getPivot());
|
|
|
-
|
|
|
- cp.positionHandle = this.createHandle(cp.position, 'red');
|
|
|
- cp.targetHandle = this.createHandle(cp.target, 'blue');
|
|
|
-
|
|
|
- this.controlPoints.splice(index, 0, cp);
|
|
|
+
|
|
|
+ this.posCurve.addPoint(position, index)
|
|
|
+ this.targetCurve.addPoint(target, index)
|
|
|
+
|
|
|
|
|
|
this.dispatchEvent({
|
|
|
- type: "controlpoint_added",
|
|
|
- controlpoint: cp,
|
|
|
+ type: "controlpoint_added",
|
|
|
+ index
|
|
|
});
|
|
|
|
|
|
- return cp;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
- removeControlPoint(cp){
|
|
|
- this.controlPoints = this.controlPoints.filter(_cp => _cp !== cp);
|
|
|
-
|
|
|
- this.dispatchEvent({
|
|
|
+
|
|
|
+ removeControlPoint(index){
|
|
|
+ this.posCurve.removePoint(index)
|
|
|
+ this.targetCurve.removePoint(index)
|
|
|
+ this.dispatchEvent({
|
|
|
type: "controlpoint_removed",
|
|
|
- controlpoint: cp,
|
|
|
+ index
|
|
|
});
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
- cp.positionHandle.svg.remove();
|
|
|
- cp.targetHandle.svg.remove();
|
|
|
|
|
|
- // TODO destroy cp
|
|
|
- }
|
|
|
|
|
|
createPath(){
|
|
|
-
|
|
|
- { // position
|
|
|
- const geometry = new LineGeometry();
|
|
|
-
|
|
|
- let material = new LineMaterial({
|
|
|
- color: 0x00ff00,
|
|
|
- dashSize: 5,
|
|
|
- gapSize: 2,
|
|
|
- lineWidth: 2,
|
|
|
- resolution: new THREE.Vector2(1000, 1000),
|
|
|
- });
|
|
|
-
|
|
|
- const line = new Line2(geometry, material);
|
|
|
-
|
|
|
- this.line = line;
|
|
|
- this.node.add(line);
|
|
|
- }
|
|
|
-
|
|
|
- { // target
|
|
|
- const geometry = new LineGeometry();
|
|
|
-
|
|
|
- let material = new LineMaterial({
|
|
|
- color: 0x0000ff,
|
|
|
- dashSize: 5,
|
|
|
- gapSize: 2,
|
|
|
- lineWidth: 2,
|
|
|
- resolution: new THREE.Vector2(1000, 1000),
|
|
|
- });
|
|
|
-
|
|
|
- const line = new Line2(geometry, material);
|
|
|
-
|
|
|
- this.targetLine = line;
|
|
|
- this.node.add(line);
|
|
|
- }
|
|
|
+ this.posCurve = new CurveCtrl([],getLineMat('position'), colors.position);
|
|
|
+ this.targetCurve = new CurveCtrl([], getLineMat('target'), colors.target);
|
|
|
+ this.node.add(this.posCurve)
|
|
|
+ this.node.add(this.targetCurve)
|
|
|
}
|
|
|
|
|
|
createFrustum(){
|
|
@@ -274,105 +202,39 @@ export class CameraAnimation extends EventDispatcher{
|
|
|
const f = 0.3;
|
|
|
|
|
|
const positions = [
|
|
|
- 0, 0, 0,
|
|
|
- -f, -f, +1,
|
|
|
-
|
|
|
- 0, 0, 0,
|
|
|
- f, -f, +1,
|
|
|
-
|
|
|
- 0, 0, 0,
|
|
|
- f, f, +1,
|
|
|
+ new THREE.Vector3( 0, 0, 0),
|
|
|
+ new THREE.Vector3(-f, -f, +1),
|
|
|
|
|
|
- 0, 0, 0,
|
|
|
- -f, f, +1,
|
|
|
+ new THREE.Vector3( 0, 0, 0),
|
|
|
+ new THREE.Vector3( f, -f, +1),
|
|
|
|
|
|
- -f, -f, +1,
|
|
|
- f, -f, +1,
|
|
|
+ new THREE.Vector3( 0, 0, 0),
|
|
|
+ new THREE.Vector3( f, f, +1),
|
|
|
|
|
|
- f, -f, +1,
|
|
|
- f, f, +1,
|
|
|
+ new THREE.Vector3( 0, 0, 0),
|
|
|
+ new THREE.Vector3(-f, f, +1),
|
|
|
|
|
|
- f, f, +1,
|
|
|
- -f, f, +1,
|
|
|
+ new THREE.Vector3(-f, -f, +1),
|
|
|
+ new THREE.Vector3( f, -f, +1),
|
|
|
|
|
|
- -f, f, +1,
|
|
|
- -f, -f, +1,
|
|
|
- ];
|
|
|
+ new THREE.Vector3( f, -f, +1),
|
|
|
+ new THREE.Vector3( f, f, +1),
|
|
|
|
|
|
- const geometry = new LineGeometry();
|
|
|
+ new THREE.Vector3( f, f, +1),
|
|
|
+ new THREE.Vector3(-f, f, +1),
|
|
|
|
|
|
- geometry.setPositions(positions);
|
|
|
- geometry.verticesNeedUpdate = true;
|
|
|
- geometry.computeBoundingSphere();
|
|
|
+ new THREE.Vector3(-f, f, +1),
|
|
|
+ new THREE.Vector3(-f, -f, +1),
|
|
|
+ ]
|
|
|
|
|
|
- let material = new LineMaterial({
|
|
|
- color: 0xff0000,
|
|
|
- lineWidth: 2,
|
|
|
- resolution: new THREE.Vector2(1000, 1000),
|
|
|
- });
|
|
|
-
|
|
|
- const line = new Line2(geometry, material);
|
|
|
- line.computeLineDistances();
|
|
|
-
|
|
|
+
|
|
|
+ //geometry.computeBoundingSphere();//?
|
|
|
+ const line = LineDraw.createFatLine( positions, {material:getLineMat('frustum')})
|
|
|
+ //line.scale.set(20, 20, 20);
|
|
|
return line;
|
|
|
}
|
|
|
|
|
|
- updatePath(){
|
|
|
-
|
|
|
- { // positions
|
|
|
- const positions = this.controlPoints.map(cp => cp.position);
|
|
|
- const first = positions[0];
|
|
|
-
|
|
|
- const curve = new THREE.CatmullRomCurve3(positions);
|
|
|
- curve.curveType = this.curveType;
|
|
|
-
|
|
|
- const n = 100;
|
|
|
-
|
|
|
- const curvePositions = [];
|
|
|
- for(let k = 0; k <= n; k++){
|
|
|
- const t = k / n;
|
|
|
-
|
|
|
- const position = curve.getPoint(t).sub(first);
|
|
|
-
|
|
|
- curvePositions.push(position.x, position.y, position.z);
|
|
|
- }
|
|
|
-
|
|
|
- this.line.geometry.setPositions(curvePositions);
|
|
|
- this.line.geometry.verticesNeedUpdate = true;
|
|
|
- this.line.geometry.computeBoundingSphere();
|
|
|
- this.line.position.copy(first);
|
|
|
- this.line.computeLineDistances();
|
|
|
-
|
|
|
- this.cameraCurve = curve;
|
|
|
- }
|
|
|
-
|
|
|
- { // targets
|
|
|
- const positions = this.controlPoints.map(cp => cp.target);
|
|
|
- const first = positions[0];
|
|
|
-
|
|
|
- const curve = new THREE.CatmullRomCurve3(positions);
|
|
|
- curve.curveType = this.curveType;
|
|
|
-
|
|
|
- const n = 100;
|
|
|
-
|
|
|
- const curvePositions = [];
|
|
|
- for(let k = 0; k <= n; k++){
|
|
|
- const t = k / n;
|
|
|
-
|
|
|
- const position = curve.getPoint(t).sub(first);
|
|
|
-
|
|
|
- curvePositions.push(position.x, position.y, position.z);
|
|
|
- }
|
|
|
-
|
|
|
- this.targetLine.geometry.setPositions(curvePositions);
|
|
|
- this.targetLine.geometry.verticesNeedUpdate = true;
|
|
|
- this.targetLine.geometry.computeBoundingSphere();
|
|
|
- this.targetLine.position.copy(first);
|
|
|
- this.targetLine.computeLineDistances();
|
|
|
-
|
|
|
- this.targetCurve = curve;
|
|
|
- }
|
|
|
- }
|
|
|
+
|
|
|
|
|
|
at(t){
|
|
|
|
|
@@ -382,7 +244,7 @@ export class CameraAnimation extends EventDispatcher{
|
|
|
t = 0;
|
|
|
}
|
|
|
|
|
|
- const camPos = this.cameraCurve.getPointAt(t);
|
|
|
+ const camPos = this.posCurve.getPointAt(t);
|
|
|
const target = this.targetCurve.getPointAt(t);
|
|
|
|
|
|
const frame = {
|
|
@@ -397,87 +259,13 @@ export class CameraAnimation extends EventDispatcher{
|
|
|
this.t = t;
|
|
|
}
|
|
|
|
|
|
- createHandle(vector, color){
|
|
|
-
|
|
|
- const svgns = "http://www.w3.org/2000/svg";
|
|
|
- const svg = document.createElementNS(svgns, "svg");
|
|
|
-
|
|
|
- svg.setAttribute("width", "2em");
|
|
|
- svg.setAttribute("height", "2em");
|
|
|
- svg.setAttribute("position", "absolute");
|
|
|
-
|
|
|
- svg.style.left = "50px";
|
|
|
- svg.style.top = "50px";
|
|
|
- svg.style.position = "absolute";
|
|
|
- svg.style.zIndex = "10000";
|
|
|
-
|
|
|
- const circle = document.createElementNS(svgns, 'circle');
|
|
|
- circle.setAttributeNS(null, 'cx', "1em");
|
|
|
- circle.setAttributeNS(null, 'cy', "1em");
|
|
|
- circle.setAttributeNS(null, 'r', "0.5em");
|
|
|
- circle.setAttributeNS(null, 'style', 'fill: '+color+'; stroke: black; stroke-width: 0.2em;' );
|
|
|
- svg.appendChild(circle);
|
|
|
-
|
|
|
-
|
|
|
- const element = this.viewer.renderer.domElement.parentElement;
|
|
|
- element.appendChild(svg);
|
|
|
-
|
|
|
-
|
|
|
- const startDrag = (evt) => {
|
|
|
- this.selectedElement = svg;
|
|
|
-
|
|
|
- document.addEventListener("mousemove", drag);
|
|
|
- };
|
|
|
-
|
|
|
- const endDrag = (evt) => {
|
|
|
- this.selectedElement = null;
|
|
|
-
|
|
|
- document.removeEventListener("mousemove", drag);
|
|
|
- };
|
|
|
-
|
|
|
- const drag = (evt) => {
|
|
|
- if (this.selectedElement) {
|
|
|
- evt.preventDefault();
|
|
|
-
|
|
|
- const rect = viewer.renderer.domElement.getBoundingClientRect();
|
|
|
-
|
|
|
- const x = evt.clientX - rect.x;
|
|
|
- const y = evt.clientY - rect.y;
|
|
|
-
|
|
|
- const {width, height} = this.viewer.renderer.getSize(new THREE.Vector2());
|
|
|
- const camera = this.viewer.scene.getActiveCamera();
|
|
|
- //const cp = this.controlPoints.find(cp => cp.handle.svg === svg);
|
|
|
- const projected = vector.clone().project(camera);
|
|
|
-
|
|
|
- projected.x = ((x / width) - 0.5) / 0.5;
|
|
|
- projected.y = (-(y - height) / height - 0.5) / 0.5;
|
|
|
-
|
|
|
- const unprojected = projected.clone().unproject(camera);
|
|
|
- vector.set(unprojected.x, unprojected.y, unprojected.z);
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- svg.addEventListener('mousedown', startDrag);
|
|
|
- svg.addEventListener('mouseup', endDrag);
|
|
|
-
|
|
|
- const handle = {
|
|
|
- svg: svg,
|
|
|
- };
|
|
|
-
|
|
|
- return handle;
|
|
|
- }
|
|
|
+
|
|
|
|
|
|
setVisible(visible){
|
|
|
this.node.visible = visible;
|
|
|
-
|
|
|
- const display = visible ? "" : "none";
|
|
|
-
|
|
|
- for(const cp of this.controlPoints){
|
|
|
- cp.positionHandle.svg.style.display = display;
|
|
|
- cp.targetHandle.svg.style.display = display;
|
|
|
- }
|
|
|
+
|
|
|
+ this.posCurve.visible = visible
|
|
|
+ this.targetCurve.visible = visible
|
|
|
|
|
|
this.visible = visible;
|
|
|
}
|
|
@@ -512,18 +300,43 @@ export class CameraAnimation extends EventDispatcher{
|
|
|
viewer.scene.view.lookAt(frame.target);
|
|
|
|
|
|
|
|
|
+ this.updateFrustum()
|
|
|
+
|
|
|
+
|
|
|
if(t > 1){
|
|
|
this.setVisible(originalyVisible);
|
|
|
|
|
|
this.viewer.removeEventListener("update", onUpdate);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
};
|
|
|
|
|
|
this.viewer.addEventListener("update", onUpdate);
|
|
|
|
|
|
}
|
|
|
|
|
|
+ updateFrustum(){ //
|
|
|
+ const frame = this.at(this.t);
|
|
|
+ const frustum = this.frustum;
|
|
|
+
|
|
|
+ frustum.position.copy(frame.position);
|
|
|
+ frustum.lookAt(...frame.target.toArray());
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ changeCallback(){
|
|
|
+ this.posCurve.update()
|
|
|
+ this.targetCurve.update()
|
|
|
+ this.updateFrustum()
|
|
|
+ }
|
|
|
+
|
|
|
+ dispose(){//add
|
|
|
+ this.posCurve.dispatchEvent({type:'dispose'})
|
|
|
+ this.targetCurve.dispatchEvent({type:'dispose'})
|
|
|
+ this.node.parent.remove(this.node);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
|
+//scene.removeCameraAnimation
|