Skip to content

Commit

Permalink
add custom meshes and loader (#183)
Browse files Browse the repository at this point in the history
  • Loading branch information
ostatni5 committed Nov 19, 2021
1 parent fd8ea25 commit 0291ec1
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 57 deletions.
8 changes: 4 additions & 4 deletions src/ThreeEditor/js/Editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Strings } from './Strings.js';
import { Storage as _Storage } from './Storage.js';
import { generateSimulationInfo } from '../util/AdditionalUserData';
import { DetectManager } from '../util/Detect/DetectManager';
import { EditorObjectLoader } from '../util/ObjectLoader';

var _DEFAULT_CAMERA = new THREE.PerspectiveCamera(50, 1, 0.01, 1000);
_DEFAULT_CAMERA.name = 'Camera';
Expand All @@ -24,7 +25,6 @@ export function Editor(container) {

editScript: new Signal(),


// notifications

editorCleared: new Signal(),
Expand Down Expand Up @@ -125,7 +125,7 @@ export function Editor(container) {
this.camera = _DEFAULT_CAMERA.clone();

this.scene = new THREE.Scene();
this.scene.name = 'Scene';
this.scene.name = 'Geometries';

this.sceneHelpers = new THREE.Scene();

Expand Down Expand Up @@ -648,7 +648,7 @@ Editor.prototype = {
this.camera.copy(_DEFAULT_CAMERA);
this.signals.cameraResetted.dispatch();

this.scene.name = 'Scene';
this.scene.name = 'Geometries';
this.scene.userData = {};
this.scene.background = null;
this.scene.environment = null;
Expand Down Expand Up @@ -691,7 +691,7 @@ Editor.prototype = {

//
async fromJSON(json) {
const loader = new THREE.ObjectLoader();
const loader = new EditorObjectLoader();
const camera = await loader.parseAsync(json.camera);

this.camera.copy(camera);
Expand Down
33 changes: 5 additions & 28 deletions src/ThreeEditor/js/Menubar.Add.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as THREE from 'three';
import { BoxMesh, CylinderMesh, SphereMesh } from '../util/BasicMeshes';
import { AddObjectCommand, AddZoneCommand, AddDetectSectionCommand } from './commands/Commands';
import { UIHorizontalRule, UIPanel } from './libs/ui.js';
import { createOption } from './Menubar.js';
Expand Down Expand Up @@ -32,47 +33,23 @@ function MenubarAdd(editor) {

})).add(new UIHorizontalRule());

const material = new THREE.MeshPhongMaterial({ side: THREE.DoubleSide, transparent: true, opacity: 0.5, wireframe: true });

//https://stackoverflow.com/questions/37090942/how-to-render-clipped-surfaces-as-solid-objects/37093210#37093210
material.onBeforeCompile = function (shader) {

shader.fragmentShader = shader.fragmentShader.replace(

`gl_FragColor = vec4( outgoingLight, diffuseColor.a );`,

`gl_FragColor = ( gl_FrontFacing ) ? vec4( outgoingLight, diffuseColor.a ) : vec4( diffuse, opacity );`

);
};


// Box Sphere & Cylinder
options.add(createOption('option', strings.getKey('menubar/add/box'), () => {

const geometry = new THREE.BoxGeometry(1, 1, 1, 1, 1, 1);
const mesh = new THREE.Mesh(geometry, material.clone());
mesh.name = 'Box';
editor.execute(new AddObjectCommand(editor, new BoxMesh()));

editor.execute(new AddObjectCommand(editor, mesh));
})).add(createOption('option', strings.getKey('menubar/add/sphere'), () => {

const geometry = new THREE.SphereGeometry(1, 16, 8, 0, Math.PI * 2, 0, Math.PI);
const mesh = new THREE.Mesh(geometry, material.clone());
mesh.name = 'Sphere';
editor.execute(new AddObjectCommand(editor, new SphereMesh()));

editor.execute(new AddObjectCommand(editor, mesh));
})).add(createOption('option', strings.getKey('menubar/add/cylinder'), () => {

const geometry = new THREE.CylinderGeometry(1, 1, 1, 16, 1, false, 0, Math.PI * 2);
const mesh = new THREE.Mesh(geometry, material.clone());
mesh.name = 'Cylinder';
editor.execute(new AddObjectCommand(editor, new CylinderMesh()));

editor.execute(new AddObjectCommand(editor, mesh));
})).add(new UIHorizontalRule());

// HemisphereLight
//Code adjusted from https://github.com/mrdoob/three.js/blob/r131/editor/js/Menubar.Add.js
// Code adjusted from https://github.com/mrdoob/three.js/blob/r131/editor/js/Menubar.Add.js
options.add(createOption('option', strings.getKey('menubar/add/hemispherelight'), () => {

const skyColor = 0x00aaff; // Deep Sky Blue
Expand Down
4 changes: 4 additions & 0 deletions src/ThreeEditor/js/Sidebar.Object.js
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,10 @@ function SidebarObject(editor) {

const invisible = [objectTypeRow, objectFrustumCulledRow, objectScaleRow, objectShadowRow];

if (object.notRotatable) invisible.push(objectRotationRow);

if (object.notMovable) invisible.push(objectPositionRow);

invisible.forEach((e) => e.setDisplay('none'));

}
Expand Down
9 changes: 4 additions & 5 deletions src/ThreeEditor/js/Sidebar.Scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,12 @@ function SidebarScene(editor) {
}

function getObjectType(object) {

if (object.isDetectSection) return 'Line';
if (object.isZone) return 'Points';
if (object.isZonesContainer) return 'Camera';
if (object.isDetectSectionsContainer) return 'Line';
//TODO: Add support to different keywords in css classes # skipcq: JS-0099
if (object.isDetectSectionsContainer) return 'Line';
//TODO: Add support to different keywords in css classes # skipcq: JS-0099
if (object.isScene) return 'Scene';
if (object.isCamera) return 'Camera';
if (object.isLight) return 'Light';
Expand Down Expand Up @@ -261,13 +261,12 @@ function SidebarScene(editor) {

function refreshUI() {

const { camera, scene } = editor;
const { scene } = editor;
const { detectsContainer } = editor.detectManager;
const { zonesContainer, boundingZone } = editor.zonesManager;

const options = [];

options.push(buildOption(camera, false));
options.push(buildOption(scene, false));

function addObjects(objects, pad) {
Expand Down
10 changes: 5 additions & 5 deletions src/ThreeEditor/js/Viewport.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { SetPositionCommand, SetRotationCommand, SetScaleCommand } from './comma
import { ViewportClippedView as ViewportClipPlane } from './Viewport.ClipPlane';
import { EditorOrbitControls } from './EditorOrbitControls';
import { TransformControls } from 'three/examples/jsm/controls/TransformControls';
import { UIPanel } from "./libs/ui";
import { UIPanel } from './libs/ui';
import { ViewHelper } from './Viewport.ViewHelper';
import { ViewportCamera } from './Viewport.Camera.js';

Expand Down Expand Up @@ -34,7 +34,7 @@ export function Viewport(
const container = new UIPanel();
container.setId('ViewPanel');
container.setPosition('relative');
container.setOverflow("hidden");
container.setOverflow('hidden');
container.dom.setAttribute('tabindex', '0');


Expand All @@ -45,15 +45,15 @@ export function Viewport(
const context = canvas.getContext('2d');

const cameraPersp = new THREE.PerspectiveCamera(50, 1, 0.001, 10000);
cameraPersp.name = "Perspective";
cameraPersp.name = 'Perspective';
cameraPersp.position.copy(cameraPosition ?? new THREE.Vector3(0, 10, 10)); // default camera position other than (0,0,0) to see anything

const cameraOrtho = new THREE.OrthographicCamera(1 / - 2, 1 / 2, 1 / 2, 1 / - 2, 0.001, 10000);
cameraOrtho.name = "Orthographic";
cameraOrtho.name = 'Orthographic';
cameraOrtho.position.copy(cameraPersp.position);
cameraOrtho.zoom = 0.2;

// in clipping plane views only Orthographic camera is used, hence is "up" axis adjustment is required we do so
// in clipping plane views only Orthographic camera is used, hence is 'up' axis adjustment is required we do so
cameraUp && cameraOrtho.up.copy(cameraUp);

const cameras = [cameraOrtho, cameraPersp];
Expand Down
22 changes: 11 additions & 11 deletions src/ThreeEditor/js/ViewportObjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,30 @@ export class ViewportObjects {
getSelectable({
selectFigures = true,
selectZones = false,
selectSections = false}
):THREE.Object3D[]{
selectSections = false }
): THREE.Object3D[] {
let selectableObjects: THREE.Object3D[] = [];

if(selectFigures) selectableObjects = selectableObjects.concat(this.figures);
if(selectZones) selectableObjects = selectableObjects.concat(this.zones);
if(selectSections) selectableObjects = selectableObjects.concat(this.sections);
if (selectFigures) selectableObjects = selectableObjects.concat(this.figures);
if (selectZones) selectableObjects = selectableObjects.concat(this.zones);
if (selectSections) selectableObjects = selectableObjects.concat(this.sections);

return selectableObjects;
}

push(object:THREE.Object3D): number{
push(object: THREE.Object3D): number {

if(CSG.isZone(object)) this.zones.push(object);
else if(isDetectSection(object)) this.sections.push(object);
if (CSG.isZone(object)) this.zones.push(object);
else if (isDetectSection(object)) this.sections.push(object);
else this.figures.push(object);

return this.figures.length + this.zones.length + this.sections.length;
}

cut(object:THREE.Object3D): number{
cut(object: THREE.Object3D): number {

if(CSG.isZone(object)) this.zones.splice(this.zones.indexOf(object), 1);
else if(isDetectSection(object)) this.sections.splice(this.sections.indexOf(object), 1);
if (CSG.isZone(object)) this.zones.splice(this.zones.indexOf(object), 1);
else if (isDetectSection(object)) this.sections.splice(this.sections.indexOf(object), 1);
else this.figures.splice(this.figures.indexOf(object), 1);

return this.figures.length + this.zones.length + this.sections.length;
Expand Down
49 changes: 49 additions & 0 deletions src/ThreeEditor/util/BasicMeshes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as THREE from "three";
import { ISimulationObject } from "./SimulationObject";

const defaultMaterial = new THREE.MeshPhongMaterial({ side: THREE.DoubleSide, transparent: true, opacity: 0.5, wireframe: true });

//https://stackoverflow.com/questions/37090942/how-to-render-clipped-surfaces-as-solid-objects/37093210#37093210
defaultMaterial.onBeforeCompile = function (shader) {

shader.fragmentShader = shader.fragmentShader.replace(

`gl_FragColor = vec4( outgoingLight, diffuseColor.a );`,

`gl_FragColor = ( gl_FrontFacing ) ? vec4( outgoingLight, diffuseColor.a ) : vec4( diffuse, opacity );`

);
};

const boxGeometry = new THREE.BoxGeometry(1, 1, 1, 1, 1, 1);

export class BoxMesh extends THREE.Mesh<THREE.BoxGeometry> implements ISimulationObject {
type = 'BoxMesh';
name = 'Box';
constructor(geometry?: THREE.BoxGeometry, material?: THREE.Material) {
super(geometry ?? boxGeometry, material ?? defaultMaterial.clone());
}
}


const cylinderGeometry = new THREE.CylinderGeometry(1, 1, 1, 16, 1, false, 0, Math.PI * 2);

export class CylinderMesh extends THREE.Mesh<THREE.CylinderGeometry> implements ISimulationObject {
type = 'CylinderMesh';
name = 'Cylinder';
constructor(geometry?: THREE.CylinderGeometry, material?: THREE.Material) {
super(geometry ?? cylinderGeometry, material ?? defaultMaterial.clone());
}
}


const sphereGeometry = new THREE.SphereGeometry(1, 16, 8, 0, Math.PI * 2, 0, Math.PI);

export class SphereMesh extends THREE.Mesh<THREE.SphereGeometry> implements ISimulationObject {
readonly notRotatable = true;
type = 'SphereMesh';
name = 'Sphere';
constructor(geometry?: THREE.SphereGeometry, material?: THREE.Material) {
super(geometry ?? sphereGeometry, material ?? defaultMaterial.clone());
}
}
41 changes: 41 additions & 0 deletions src/ThreeEditor/util/ObjectLoader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Object3D, ObjectLoader } from "three";
import { BoxMesh, CylinderMesh, SphereMesh } from "./BasicMeshes";

export class EditorObjectLoader extends ObjectLoader {

parseObject<T extends Object3D<THREE.Event>>(data: any, geometries: any[], materials: THREE.Material[], animations: THREE.AnimationClip[]): T {
const geometry = geometries[data.geometry];
const material = materials[data.material];

let object = super.parseObject<T>(data, geometries, materials, animations);
let editorObject;
switch (data.type) {
case 'SphereMesh':
editorObject = new SphereMesh();
break;
case 'BoxMesh':
editorObject = new BoxMesh();
break;
case 'CylinderMesh':
editorObject = new CylinderMesh();
break;
default:
// not custom object type
}

// rewrite properties from parsed data if object is custom
if (editorObject) {

// hacky way to copy parsed data
editorObject.copy(object as any);

editorObject.uuid = object.uuid;
editorObject.material = material;
editorObject.geometry = geometry;

return editorObject as Object3D<THREE.Event> as T;
}

return object;
}
}
9 changes: 5 additions & 4 deletions src/ThreeEditor/util/SimulationObject.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export interface ISimulationObject {
notRemovable: boolean,
notMovable: boolean,
notRotatable: boolean,
notScalable: boolean,
readonly isObject3D: true;
readonly notRemovable?: boolean,
readonly notMovable?: boolean,
readonly notRotatable?: boolean,
readonly notScalable?: boolean,
}

0 comments on commit 0291ec1

Please sign in to comment.