How to use OrthographicCamera and drag objects in Three.js Editor?

Hi everyone,
How can I drag the red Mesh object under OrthographicCamera? :thinking:

This is the code of Menubar.Rack.js

import * as THREE from '../../build/three.module.js';

import { UIPanel, UIRow, UIHorizontalRule } from './libs/ui.js'; // UIHorizontalRule 為水平線

import { AmbientLight } from '../../../threejsEditor/src/lights/AmbientLight.js';
import { DirectionalLight } from '../../../threejsEditor/src/lights/DirectionalLight.js';

import { DragControls } from '../../examples/jsm/controls/DragControls.js';

function MenubarRack(editor, viewport) {

	var strings = editor.strings;

	var container = new UIPanel();
	container.setClass('menu');

	var title = new UIPanel();
	title.setClass('title');
	title.setTextContent(strings.getKey('menubar/rack')); //
	container.add(title);

	var options = new UIPanel();
	options.setClass('options');
	container.add(options);

	// Initialize Default Camera Object

	var _DEFAULT_CAMERA_RACK = editor.camera;
	// _DEFAULT_CAMERA_RACK.uuid = '6EFH8931-382B-461V-D364-439SJRF9F0IO';
	_DEFAULT_CAMERA_RACK.name = 'Camera_Rack';
	// editor.execute( new SetValueCommand( editor, _DEFAULT_CAMERA_RACK, 'name', 'Camera_Rac' ) );
	_DEFAULT_CAMERA_RACK.position.set(0, 300, 400);
	_DEFAULT_CAMERA_RACK.far = 3000;
	_DEFAULT_CAMERA_RACK.lookAt(new THREE.Vector3());

	// Initialize loading orthographic camera 由 Y 軸俯視由上而下看,只能移動 X 軸和 Z 軸	

	var _DEFAULT_CAMERA_Y = new THREE.OrthographicCamera(-450, 450, 580, 100, 0.1, 2000);
	// _DEFAULT_CAMERA_Y.uuid = '4EFF8938-492A-461E-B364-433FDEF9F0CE';
	_DEFAULT_CAMERA_Y.name = 'CameraTest_Y';
	_DEFAULT_CAMERA_Y.position.set(0, 780, 340);
	_DEFAULT_CAMERA_Y.rotation.x = -(Math.PI / 2);

	editor.addCamera(_DEFAULT_CAMERA_Y);
	editor.execute(new AddObjectCommand(editor, _DEFAULT_CAMERA_Y));

	// Initialize loading lights

	const ambientLight = new AmbientLight(0x222222, 1);
	const directionalLight = new DirectionalLight(0xffffff, 1.1);
	directionalLight.position.set(100, 100, 100);

	ambientLight.name = 'AmbientLight';
	directionalLight.name = 'DirectionalLight';
	editor.execute(new AddObjectCommand(editor, ambientLight));
	editor.execute(new AddObjectCommand(editor, directionalLight));

	// Initialize Default Room Object

	var geometry = new THREE.BoxBufferGeometry(15, 0.1, 8, 1, 1, 1);
	var defultroom = new THREE.Mesh(geometry, new THREE.MeshStandardMaterial({ color: '#18ECFB' }));
	defultroom.name = 'DefualtRoom';
	defultroom.position.set(0, 0, 0);
	defultroom.scale.set(50, 50, 50);
	defultroom.material.transparent = true;
	defultroom.material.opacity = 0.3;

	editor.execute(new AddObjectCommand(editor, defultroom));

	// Initialize Rack Object (test)

	var geometry = new THREE.BoxBufferGeometry(2, 1, 2, 1, 1, 1);
	var defaultrack = new THREE.Mesh(geometry, new THREE.MeshStandardMaterial({ color: 'rgb(255, 0, 0)' }));
	defaultrack.name = 'TestRack';
	defaultrack.position.set(0, 0, 0);
	defaultrack.scale.set(50, 50, 50);

	editor.execute(new AddObjectCommand(editor, defaultrack));

	// 測試跳轉

	var option = new UIRow();
	option.setClass('option');
	option.setTextContent(strings.getKey('menubar/rack/test'));
	option.onClick(function () {

		window.location.assign("../../EditorRoomTest.php");// 跳轉回到模式切換測試頁面

	});
	options.add(option);

	var objects = [];

	objects.push(defaultrack);

	var renderer = new THREE.WebGLRenderer({ antialias: true });

	var controls = new DragControls(objects, _DEFAULT_CAMERA_Y, renderer.domElement);

	controls.addEventListener('drag', render);

	controls.addEventListener('dragstart', function (event) {

		event.object.material.emissive.set(0xaaaaaa);

	});

	controls.addEventListener('dragend', function (event) {

		event.object.material.emissive.set(0x000000);

	});

	console.log('Menubar.Rack.js controls:        ', controls);
	console.log('Menubar.Rack.js viewport.dom:        ', viewport.dom);

	function render() {

		renderer.render(scene, _DEFAULT_CAMERA_Y);

	}

	return container;
}

export { MenubarRack };

This is the code of Menubar.js

import { UIPanel } from './libs/ui.js';

import { MenubarAdd } from './Menubar.Add.js';
import { MenubarEdit } from './Menubar.Edit.js';
import { MenubarFile } from './Menubar.File.js';
import { MenubarExamples } from './Menubar.Examples.js';
import { MenubarHelp } from './Menubar.Help.js';
import { MenubarPlay } from './Menubar.Play.js';
import { MenubarStatus } from './Menubar.Status.js';
import { MenubarRack } from './Menubar.Rack.js'; 

function Menubar( editor,viewport) {

	var container = new UIPanel();
	container.setId( 'menubar' );

	container.add( new MenubarFile( editor ) );
	container.add( new MenubarEdit( editor ) );
	container.add( new MenubarRack( editor ,viewport) ); 
	
	container.add( new MenubarStatus( editor ) );

	return container;

}

export { Menubar };

The editor’s instance of TransformControls are created with the default editor camera:

This default camera is a perspective camera as you can see here:

TransformControls also have to use the orthographic camera in your scene otherwise the controls won’t work.

1 Like

Thank you for your reply, I will try again.

I can’t try it out. :sob:
How TransformControls reference Viewpor.jst’s dom(use the same renderer)? :thinking:

First, the Editor object in index.php has the parameter theme, and the judgment is made according to the value of the parameter theme.

index.php

<?php echo "var theme='".$theme."';";?>

var editor = new Editor(theme);

window.editor = editor; // Expose editor to Console
window.THREE = THREE; // Expose THREE to APP Scripts and Console
window.VRButton = VRButton; // Expose VRButton to APP Scripts

var viewport = new Viewport( editor, theme );
document.body.appendChild( viewport.dom );

var toolbar = new Toolbar( editor );
document.body.appendChild( toolbar.dom );

var script = new Script( editor );
document.body.appendChild( script.dom );

var player = new Player( editor );
document.body.appendChild( player.dom );

var sidebar = new Sidebar( editor );
document.body.appendChild( sidebar.dom );

var menubar = new Menubar( editor, theme);
document.body.appendChild( menubar.dom );

var resizer = new Resizer( editor );
document.body.appendChild( resizer.dom );


Second, parameter theme in Editor.js is set to the orthographic camera by default according to the value of the parameter theme.

Editor.js

import * as THREE from '../../build/three.module.js';

import { Config } from './Config.js';
import { Loader } from './Loader.js';
import { History as _History } from './History.js';
import { Strings } from './Strings.js';
import { Storage as _Storage } from './Storage.js';

var _DEFAULT_CAMERA = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.01, 1000 );
_DEFAULT_CAMERA.name = 'Camera';
_DEFAULT_CAMERA.position.set( 0, 5, 10 );
_DEFAULT_CAMERA.lookAt( new THREE.Vector3() );

function Editor(theme) {

	console.log('Editor theme:    ', theme);
	switch (theme) {
		case 'room':			
			break;
		case 'rack':			
			_DEFAULT_CAMERA = new THREE.OrthographicCamera(-50, 50, 50, -50, 0.01, 1000);
			_DEFAULT_CAMERA.name = 'OrthographicCamera';
			_DEFAULT_CAMERA.position.set(0, 20, 0);
			_DEFAULT_CAMERA.lookAt(new THREE.Vector3());
			break;
		case 'equipment':			
			break;
	}

.... Omitted below
}

Finally, the parameter theme in Viewport.js sets controls.enabled to false according to the value of the parameter theme.
Remarks: controls are the variables of EditorControls objectification.

Viewport.js

    // controls need to be added *after* main logic,
	// otherwise controls.enabled doesn't work.

	var controls = new EditorControls( camera, container.dom );

	console.log('Viewport theme:    ',  theme);
	switch (theme) {
		case 'room':			
			controls.enabled = true;
			break;
		case 'rack':			
			controls.enabled = false;
			break;
		case 'equipment':			
			break;
	}


Finally succeeded in making it, so touched!! :laughing:

1 Like