Skip to content

Commit

Permalink
feat(sample): Add sample about pick (Orillusion#124)
Browse files Browse the repository at this point in the history
Add samples about pick.
And outlinePost used in sample.
  • Loading branch information
hellmor authored May 12, 2023
1 parent 30e92d6 commit dbecd95
Show file tree
Hide file tree
Showing 5 changed files with 487 additions and 0 deletions.
28 changes: 28 additions & 0 deletions samples/pick/MaterialStateComponent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { ComponentBase, MaterialBase, MeshRenderer, LitMaterial, Color, Interpolator, Engine3D } from "@orillusion/core";

export class MaterialStateComponent extends ComponentBase {
private _materials: MaterialBase[];

start() {
let renderer = this.object3D.getComponent(MeshRenderer);
if (renderer) {
this._materials = renderer.materials;
for (let i = 0; i < this._materials.length; i++) {
if (this._materials[i] instanceof LitMaterial) {
const element = this._materials[i] as LitMaterial;
element.emissiveMap = Engine3D.res.whiteTexture;
element.emissiveColor = new Color(0, 0, 0, 0);
}
}
}
}

public changeColor(tartColor: Color, time: number) {
for (let i = 0; i < this._materials.length; i++) {
let material = this._materials[i] as LitMaterial;
material.emissiveColor = tartColor;
Interpolator.to(material, { emissiveIntensity: tartColor.a }, time);
}
}

}
68 changes: 68 additions & 0 deletions samples/pick/Sample_BoxColliderPick.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { GUIHelp } from "@orillusion/debug/GUIHelp";
import { GUIUtil } from "@samples/utils/GUIUtil";
import { createExampleScene } from "@samples/utils/ExampleScene";
import { Scene3D, Engine3D, BoxGeometry, SphereGeometry, SphereColliderShape, BoxColliderShape, Vector3, Object3D, MeshRenderer, LitMaterial, ColliderComponent, PointerEvent3D, Color } from "@orillusion/core";

class Sample_BoxColliderPick {
scene: Scene3D;
async run() {
Engine3D.setting.pick.enable = true;
Engine3D.setting.pick.mode = `bound`;

// init Engine3D
await Engine3D.init({});

let exampleScene = createExampleScene();
this.scene = exampleScene.scene;

GUIHelp.init();

GUIUtil.renderDirLight(exampleScene.light, false);
Engine3D.startRenderView(exampleScene.view);

this.initPickObject(this.scene);
}

//create some interactive boxes
private initPickObject(scene: Scene3D): void {
let size: number = 9;

//geometry
let boxGeometry = new BoxGeometry(size, size, size);
let sphereGeometry = new SphereGeometry(size / 2, 20, 20);

//collider shape
let sphereShape = new SphereColliderShape(size / 2);
let boxShape = new BoxColliderShape().setFromCenterAndSize(new Vector3(0, 0, 0), new Vector3(size, size, size));

for (let i = 0; i < 10; i++) {
let obj = new Object3D();
obj.name = 'sphere ' + i;
scene.addChild(obj);
obj.x = (i - 5) * 15;
let renderer = obj.addComponent(MeshRenderer);
renderer.geometry = i % 2 ? boxGeometry : sphereGeometry;
renderer.material = new LitMaterial();

// register collider component
let collider = obj.addComponent(ColliderComponent);
collider.shape = i % 2 ? boxShape : sphereShape;
}
let pickFire = Engine3D.views[0].pickFire;
// register event
pickFire.addEventListener(PointerEvent3D.PICK_CLICK, this.onMousePick, this);
}

private onMousePick(e: PointerEvent3D) {
let pick = e.data.pick;
if (pick && pick.object3D) {
let obj = pick.object3D;
let meshRenderer = obj.getComponent(MeshRenderer);
//modify base color
meshRenderer.material.baseColor = new Color(Math.random(), Math.random(), Math.random())
}
}

}

new Sample_BoxColliderPick().run();
112 changes: 112 additions & 0 deletions samples/pick/Sample_OutlineEffectPick.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { GUIHelp } from "@orillusion/debug/GUIHelp";
import { GUIUtil } from "@samples/utils/GUIUtil";
import { createExampleScene } from "@samples/utils/ExampleScene";
import { Object3D, Scene3D, Color, Engine3D, OutlinePost, SphereGeometry, LitMaterial, MeshRenderer, ColliderComponent, PointerEvent3D, outlinePostManager } from "@orillusion/core";

class Sample_OutlineEffectPick {
lightObj: Object3D;
scene: Scene3D;
selectColor: Color;
highLightColor: Color;

constructor() {
this.selectColor = new Color(1.0, 0, 0.0, 3.0);
this.selectColor.convertToHDRRGB();

this.highLightColor = new Color(0.0, 1.0, 1.0, 3);
this.highLightColor.convertToHDRRGB();
}

async run() {
Engine3D.setting.pick.enable = true;
Engine3D.setting.pick.mode = `pixel`;

Engine3D.setting.render.postProcessing.outline.outlinePixel = 1;
Engine3D.setting.render.postProcessing.outline.fadeOutlinePixel = 4;
Engine3D.setting.render.postProcessing.outline.strength = 0.25;

// init Engine3D
await Engine3D.init({});

let exampleScene = createExampleScene();
this.scene = exampleScene.scene;

GUIHelp.init();
GUIUtil.renderDirLight(exampleScene.light, false);

let job = Engine3D.startRenderView(exampleScene.view);
job.addPost(new OutlinePost());

this.initPickObject(this.scene);
}

private initPickObject(scene: Scene3D): void {
let size: number = 9;
let geometry = new SphereGeometry(size / 2, 20, 20);
for (let i = 0; i < 10; i++) {
let obj = new Object3D();
obj.name = 'sphere ' + i;
scene.addChild(obj);
obj.x = (i - 5) * 10;

let mat = new LitMaterial();
mat.emissiveMap = Engine3D.res.grayTexture;
mat.emissiveIntensity = 0.0;

let renderer = obj.addComponent(MeshRenderer);
renderer.geometry = geometry;
renderer.material = mat;

// register collider component
obj.addComponent(ColliderComponent);
}

let pickFire = Engine3D.views[0].pickFire;
// register event
pickFire.addEventListener(PointerEvent3D.PICK_UP, this.onMouseUp, this);
pickFire.addEventListener(PointerEvent3D.PICK_DOWN, this.onMouseDown, this);
pickFire.addEventListener(PointerEvent3D.PICK_CLICK, this.onMousePick, this);
pickFire.addEventListener(PointerEvent3D.PICK_OVER, this.onMouseOver, this);
pickFire.addEventListener(PointerEvent3D.PICK_OUT, this.onMouseOut, this);
pickFire.addEventListener(PointerEvent3D.PICK_MOVE, this.onMouseMove, this);
}

private onMouseUp(e: PointerEvent3D) {
if (e.target) {
outlinePostManager.clearOutline();
}
}

private onMouseDown(e: PointerEvent3D) {
if (e.target) {
outlinePostManager.setOutline([e.target], this.selectColor);
}
}

private onMousePick(e: PointerEvent3D) {
if (e.target) {
outlinePostManager.setOutline([e.target], this.selectColor);
}
}

private onMouseOver(e: PointerEvent3D) {
if (e.target) {
outlinePostManager.setOutline([e.target], this.highLightColor);
}
}

private onMouseOut(e: PointerEvent3D) {
if (e.target) {
outlinePostManager.clearOutline();
}
}

private onMouseMove(e: PointerEvent3D) {
if (e.target) {
console.log("onMove -> ", e.target.name);
}
}

}

new Sample_OutlineEffectPick().run();
130 changes: 130 additions & 0 deletions samples/pick/Sample_PixelPick.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { GUIHelp } from "@orillusion/debug/GUIHelp";
import { MaterialStateComponent } from "@samples/pick/MaterialStateComponent";
import { GUIUtil } from "@samples/utils/GUIUtil";
import { createExampleScene } from "@samples/utils/ExampleScene";
import { Scene3D, Engine3D, MeshRenderer, ColliderComponent, PointerEvent3D, SphereGeometry, Object3D, LitMaterial, Color } from "@orillusion/core";

class Sample_PixelPick {
scene: Scene3D;

async run() {
Engine3D.setting.pick.enable = true;
Engine3D.setting.pick.mode = `pixel`;
// init Engine3D
await Engine3D.init({});

let exampleScene = createExampleScene();
this.scene = exampleScene.scene;

Engine3D.startRenderView(exampleScene.view);

GUIHelp.init();
GUIUtil.renderDirLight(exampleScene.light, false);

await this.initPickObject(this.scene);

this.registerEvents();
}

private registerEvents() {
// register event
let pickFire = this.scene.view.pickFire;
pickFire.addEventListener(PointerEvent3D.PICK_UP, this.onMouseUp, this);
pickFire.addEventListener(PointerEvent3D.PICK_DOWN, this.onMouseDown, this);
pickFire.addEventListener(PointerEvent3D.PICK_CLICK, this.onMousePick, this);
pickFire.addEventListener(PointerEvent3D.PICK_OVER, this.onMouseOver, this);
pickFire.addEventListener(PointerEvent3D.PICK_OUT, this.onMouseOut, this);
}

private async initPickObject(scene: Scene3D) {
//load model
let wukong = await Engine3D.res.loadGltf('gltfs/wukong/wukong.gltf');
this.scene.addChild(wukong);

wukong.transform.x = 50;
wukong.transform.scaleX = 10;
wukong.transform.scaleY = 10;
wukong.transform.scaleZ = 10;

// register events
wukong.forChild((node) => {
if (node.hasComponent(MeshRenderer)) {
node.addComponent(MaterialStateComponent);
node.addComponent(ColliderComponent);
}
});

// add sphere list and register mouse events
let size: number = 9;
let geometry = new SphereGeometry(size / 2, 20, 20);
for (let i = 0; i < 10; i++) {
let obj = new Object3D();
obj.name = 'sphere ' + i;
scene.addChild(obj);
obj.x = (i - 5) * 10;

let mat = new LitMaterial();
mat.roughness = i / 10;
mat.metallic_max = 1.0;
mat.metallic_min = 0.0;
mat.metallic = 0.6;

let renderer = obj.addComponent(MeshRenderer);
renderer.geometry = geometry;
renderer.material = mat;

obj.addComponent(MaterialStateComponent);

// register collider component
obj.addComponent(ColliderComponent);
}
}

private getPickObject(e: PointerEvent3D): Object3D {
let pick = e.data.pick;
return pick ? pick.object3D : null;
}

private onMouseUp(e: PointerEvent3D) {
let obj = this.getPickObject(e);
if (obj) {
let msc = obj.getComponent(MaterialStateComponent);
msc.changeColor(new Color(2, 0, 0, 1), 120);
}
}

private onMouseDown(e: PointerEvent3D) {
let obj = this.getPickObject(e);
if (obj) {
let msc = obj.getComponent(MaterialStateComponent);
msc.changeColor(new Color(2, 2, 0, 1), 120);
}
}

private onMousePick(e: PointerEvent3D) {
let obj = this.getPickObject(e);
if (obj) {
let msc = obj.getComponent(MaterialStateComponent);
msc.changeColor(new Color(2, 0, 0, 1), 120);
}
}

private onMouseOver(e: PointerEvent3D) {
let obj = this.getPickObject(e);
if (obj) {
let msc = obj.getComponent(MaterialStateComponent);
msc.changeColor(new Color(1, 0.64, 0.8, 2.5), 100);
}
}

private onMouseOut(e: PointerEvent3D) {
let obj = this.getPickObject(e);
if (obj) {
let msc = obj.getComponent(MaterialStateComponent);
msc.changeColor(new Color(0, 0, 0), 120);
}
}

}

new Sample_PixelPick().run();
Loading

0 comments on commit dbecd95

Please sign in to comment.