Jelajahi Sumber

Allow scene to be viewed through any camera

Temdog007 6 tahun lalu
induk
melakukan
240f05c7aa

+ 5 - 0
editor/css/dark.css

@@ -18,6 +18,11 @@ button {
 		background-color: #08f;
 	}
 
+	button[viewset] {
+		color : #ffff00;
+		background-color: #ff0000;
+	}
+
 input, textarea {
 	background-color: #222;
 	border: 1px solid transparent;

+ 5 - 0
editor/css/light.css

@@ -16,6 +16,11 @@ button {
 		background-color: #fff;
 	}
 
+	button[viewset] {
+		color : #ffff00;
+		background-color: #ff0000;
+	}
+
 input, textarea {
 	border: 1px solid transparent;
 	color: #444;

+ 1 - 0
editor/js/Editor.js

@@ -80,6 +80,7 @@ var Editor = function () {
 	this.loader = new Loader( this );
 
 	this.camera = this.DEFAULT_CAMERA.clone();
+	this.currentCamera = null;
 
 	this.scene = new THREE.Scene();
 	this.scene.name = 'Scene';

+ 130 - 6
editor/js/Sidebar.Object.js

@@ -312,6 +312,128 @@ Sidebar.Object = function ( editor ) {
 
 	container.add( objectUserDataRow );
 
+	// view from camera
+	var cameraViewRow = new UI.Row().setDisplay( editor.selected !== null && editor.selected.isCamera ? 'block' : 'none' );
+	container.add( cameraViewRow );
+
+	var cameraViewButton = new UI.Button( strings.getKey( 'sidebar/object/view' ) );
+	var cameraTransitioning = false;
+	var transitionCamera = new THREE.PerspectiveCamera();
+	cameraViewButton.onClick( function () {
+
+		if ( editor.selected.isCamera === true && cameraTransitioning === false ) {
+
+			editor.currentCamera = transitionCamera;
+			transitionCamera.copy( editor.selected );
+			cameraViewButton.dom.setAttribute( 'viewset', '' );
+
+			var start = getCameraData( editor.camera );
+			var end = getCameraData( transitionCamera );
+			startCameraTransition( start, end );
+
+		}
+
+	} );
+
+	cameraViewButton.onMouseOut( function () {
+
+		if ( editor.currentCamera === transitionCamera ) {
+
+			cameraViewButton.dom.removeAttribute( 'viewset' );
+
+			var start = getCameraData( transitionCamera );
+			var end = getCameraData( editor.camera );
+			startCameraTransition( start, end, true );
+
+		}
+
+	} );
+
+	cameraViewRow.add( cameraViewButton );
+
+	function startCameraTransition( start, end, clearCamera ) {
+
+		var func = cameraTransition( start, end, clearCamera );
+		var result = { done: false };
+		function run() {
+
+			if ( result.done !== true ) {
+
+				result = func.next();
+				setTimeout( run );
+
+			}
+
+		}
+		run();
+
+	}
+
+	function* cameraTransition( start, end, clearCamera ) {
+
+		while ( cameraTransitioning === true ) {
+
+			yield;
+
+		}
+
+		cameraTransitioningng = true;
+
+		var startTime = performance.now();
+		var t = 0;
+		do {
+
+			transitionCamera.position.lerpVectors( start.position, end.position, t );
+			THREE.Quaternion.slerp( start.quaternion, end.quaternion, transitionCamera.quaternion, t );
+
+			transitionCamera.far = lerpValue( start.far, end.far, t );
+			transitionCamera.fov = lerpValue( start.fov, end.fov, t );
+			transitionCamera.near = lerpValue( start.near, end.near, t );
+			transitionCamera.aspect = lerpValue( start.aspect, end.aspect, t );
+
+			transitionCamera.updateProjectionMatrix();
+			signals.cameraChanged.dispatch();
+			yield;
+
+			t = Math.min( 1, ( performance.now() - startTime ) / 250 );
+
+		} while ( t !== 1 );
+
+		transitionCamera.position.copy( end.position );
+		transitionCamera.quaternion.copy( end.quaternion );
+		transitionCamera.far = end.far;
+		transitionCamera.fov = end.fov;
+		transitionCamera.near = end.near;
+		transitionCamera.aspect = end.aspect;
+
+		if ( clearCamera ) editor.currentCamera = null;
+
+
+		signals.cameraChanged.dispatch();
+
+		cameraTransitioning = false;
+
+	}
+
+	function getCameraData( camera ) {
+
+		return {
+			position: camera.position.clone(),
+			quaternion: camera.quaternion.clone(),
+			fov: camera.fov,
+			near: camera.near,
+			far: camera.far,
+			aspect: camera.aspect
+		};
+
+	}
+
+	function lerpValue( a, b, t ) {
+
+		return a + ( b - a ) * t;
+
+	}
+
 
 	//
 
@@ -523,12 +645,12 @@ Sidebar.Object = function ( editor ) {
 			'intensity': objectIntensityRow,
 			'color': objectColorRow,
 			'groundColor': objectGroundColorRow,
-			'distance' : objectDistanceRow,
-			'angle' : objectAngleRow,
-			'penumbra' : objectPenumbraRow,
-			'decay' : objectDecayRow,
-			'castShadow' : objectShadowRow,
-			'receiveShadow' : objectReceiveShadow,
+			'distance': objectDistanceRow,
+			'angle': objectAngleRow,
+			'penumbra': objectPenumbraRow,
+			'decay': objectDecayRow,
+			'castShadow': objectShadowRow,
+			'receiveShadow': objectReceiveShadow,
 			'shadow': objectShadowRadius
 		};
 
@@ -689,6 +811,8 @@ Sidebar.Object = function ( editor ) {
 
 		}
 
+		cameraViewRow.setDisplay( object.isCamera === true ? 'block' : 'none' );
+
 		objectVisible.setValue( object.visible );
 		objectFrustumCulled.setValue( object.frustumCulled );
 		objectRenderOrder.setValue( object.renderOrder );

+ 1 - 0
editor/js/Strings.js

@@ -97,6 +97,7 @@ var Strings = function ( config ) {
 			'sidebar/object/frustumcull': 'Frustum Cull',
 			'sidebar/object/renderorder': 'Render Order',
 			'sidebar/object/userdata': 'User data',
+			'sidebar/object/view': 'Set View',
 
 			'sidebar/geometry/type': 'Type',
 			'sidebar/geometry/new': 'New',

+ 11 - 3
editor/js/Viewport.js

@@ -549,11 +549,19 @@ var Viewport = function ( editor ) {
 		sceneHelpers.updateMatrixWorld();
 		scene.updateMatrixWorld();
 
-		renderer.render( scene, camera );
+		if ( editor.currentCamera !== null ) {
 
-		if ( renderer instanceof THREE.RaytracingRenderer === false ) {
+			renderer.render( scene, editor.currentCamera );
 
-			renderer.render( sceneHelpers, camera );
+		} else {
+
+			renderer.render( scene, camera );
+
+			if ( renderer instanceof THREE.RaytracingRenderer === false ) {
+
+				renderer.render( sceneHelpers, camera );
+
+			}
 
 		}