Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(HoverCameraController):Using HoverCameraController together with UIButton may result in a conflict #390

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
284 changes: 284 additions & 0 deletions samples/physics/Sample_EatTheBox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
import { BoxGeometry, Camera3D, Engine3D, LitMaterial, MeshRenderer, Object3D, Scene3D, View3D, Object3DUtil, Vector3, AtmosphericComponent, ColliderComponent, BoxColliderShape, KeyEvent, SphereColliderShape, DirectLight, SphereGeometry, ComponentBase, KeyCode, KelvinUtil, Time } from "@orillusion/core";
import { Stats } from "@orillusion/stats";
import { Ammo, Physics, Rigidbody } from "@orillusion/physics";
import dat from "dat.gui";

class Sample_EatTheBox {
view: View3D;
ammoWorld: Ammo.btDiscreteDynamicsWorld;
foods: Object3D[] = [];
dispatcher: Ammo.btDispatcher;
numManifolds: number;
Manifold: Ammo.btPersistentManifold;
objIndex: number;
tempObj: Object3D;
score: number = 0;
moveScript: MoveScript;
async run() {
//init physics and engine
await Physics.init();
await Engine3D.init({
renderLoop: () => this.loop()
});

//set shadow
Engine3D.setting.shadow.updateFrameRate = 1;
Engine3D.setting.shadow.shadowSize = 2048;
Engine3D.setting.shadow.shadowBound = 64;
//get original ammo world for processing more custom function
this.ammoWorld = Physics.world;

//create scene,add sky and FPS
let scene = new Scene3D();
let sky = scene.addComponent(AtmosphericComponent);
scene.addComponent(Stats);

//create camera
let cameraObj = new Object3D();
let camera = cameraObj.addComponent(Camera3D);
// camera.enableCSM = true;
camera.perspective(60, Engine3D.aspect, 1, 5000);
camera.lookAt(new Vector3(0, 40, 35), new Vector3());
scene.addChild(cameraObj);

//add DirectLight
let lightObj = new Object3D();
let light = lightObj.addComponent(DirectLight);
light.intensity = 50;
light.castShadow = true;
lightObj.rotationX = 60;
lightObj.rotationY = 80;
sky.relativeTransform = light.transform;
light.lightColor = KelvinUtil.color_temperature_to_rgb(5355);
scene.addChild(lightObj);

//create view
this.view = new View3D();
this.view.scene = scene;
this.view.camera = camera;

//create floor and wall
this.createFloor();
//create foods(box)
this.createFoods();
//create player(ball)
this.createBall();
//start render
Engine3D.startRenderView(this.view);

//add debug UI
const gui = new dat.GUI();
let tip = gui.addFolder("Orillusion");
tip.add({ tip1: "press wasd to move" }, "tip1");
tip.add({ tip2: "eat box to get score" }, "tip2");
tip.add(this, "score").listen();
tip.add(this.moveScript, "moveSpeed", 10, 50, 1);
tip.open();
}
private createFloor() {
//create floor and wall
let floor = Object3DUtil.GetSingleCube(50, 1, 50, 0.3, 0.3, 0.6);
let border1 = Object3DUtil.GetSingleCube(50, 5, 1, 0.3, 0.3, 0.6);
let border2 = Object3DUtil.GetSingleCube(50, 5, 1, 0.3, 0.3, 0.6);
let border3 = Object3DUtil.GetSingleCube(50, 5, 1, 0.3, 0.3, 0.6);
let border4 = Object3DUtil.GetSingleCube(50, 5, 1, 0.3, 0.3, 0.6);
//set their mass to 0,because they are static
let rigidbody = floor.addComponent(Rigidbody);
let rigidbody1 = border1.addComponent(Rigidbody);
let rigidbody2 = border2.addComponent(Rigidbody);
let rigidbody3 = border3.addComponent(Rigidbody);
let rigidbody4 = border4.addComponent(Rigidbody);
rigidbody.mass = rigidbody1.mass = rigidbody2.mass = rigidbody3.mass = rigidbody4.mass = 0;
//add collider component ,collider shape and size is same as their geometry
let collider = floor.addComponent(ColliderComponent);
collider.shape = new BoxColliderShape();
collider.shape.size = new Vector3(50, 1, 50);
let colshape = new BoxColliderShape();
colshape.size = new Vector3(50, 5, 1);
let collider1 = border1.addComponent(ColliderComponent);
let collider2 = border2.addComponent(ColliderComponent);
let collider3 = border3.addComponent(ColliderComponent);
let collider4 = border4.addComponent(ColliderComponent);
collider1.shape = collider2.shape = collider3.shape = collider4.shape = colshape;
//place the floor and walls
border1.y = 3;
border1.z = 24.5;
border2.y = 3;
border2.z = -24.5;
border3.y = 3;
border3.x = 24.5;
border3.rotationY = 90;
border4.y = 3;
border4.x = -24.5;
border4.rotationY = 90;
//set friction and restitution
rigidbody.rollingFriction = 10;
rigidbody1.restitution = rigidbody2.restitution = rigidbody3.restitution = rigidbody4.restitution = 0.3;
//set their index to -1
rigidbody.addInitedFunction(() => {
rigidbody.btRigidbody.setUserIndex(-1);
}, this);
rigidbody1.addInitedFunction(() => {
rigidbody1.btRigidbody.setUserIndex(-1);
}, this);
rigidbody2.addInitedFunction(() => {
rigidbody2.btRigidbody.setUserIndex(-1);
}, this);
rigidbody3.addInitedFunction(() => {
rigidbody3.btRigidbody.setUserIndex(-1);
}, this);
rigidbody4.addInitedFunction(() => {
rigidbody4.btRigidbody.setUserIndex(-1);
}, this);
this.view.scene.addChild(floor);
this.view.scene.addChild(border1);
this.view.scene.addChild(border2);
this.view.scene.addChild(border3);
this.view.scene.addChild(border4);
}
private createFoods() {
//create the sample food
let boxobj = new Object3D();
let mr = boxobj.addComponent(MeshRenderer);
mr.geometry = new BoxGeometry(2, 2, 2);
mr.material = new LitMaterial();
let boxColliderShape = new BoxColliderShape();
boxColliderShape.size = new Vector3(2, 2, 2);
//create 10 food box
for (let index = 0; index < 10; index++) {
let boxObj = boxobj.clone();
boxObj.y = 2;
//random position
boxObj.x = Math.random() * 40 - 20;
boxObj.z = Math.random() * 40 - 20;
let rig = boxObj.addComponent(Rigidbody);
rig.mass = 0;
let col = boxObj.addComponent(ColliderComponent);
col.shape = boxColliderShape;
rig.addInitedFunction(() => {
//get original rigidbody to get/set more property
let btrig = rig.btRigidbody;
//set this colider as trigger,trigger will not respond to collision
btrig.setCollisionFlags(4);
//set index to 0~9
btrig.setUserIndex(index);
this.foods[index] = boxObj;
}, this);
boxObj.addComponent(RotateScript);
this.view.scene.addChild(boxObj);
}
}
private createBall() {
//add player(ball)
let sphereObj = new Object3D();
let mr = sphereObj.addComponent(MeshRenderer);
mr.geometry = new SphereGeometry(1, 20, 20);
let mat = new LitMaterial();
mr.material = mat;
mat.baseColor = KelvinUtil.color_temperature_to_rgb(1325);
sphereObj.y = 5;
//add movescript
this.moveScript = sphereObj.addComponent(MoveScript);
this.moveScript.rigidbody = sphereObj.addComponent(Rigidbody);
this.moveScript.rigidbody.addInitedFunction(() => {
this.moveScript.rigidbody.btRigidbody.setUserIndex(-1);
}, this);
this.moveScript.rigidbody.mass = 10;
let collider = sphereObj.addComponent(ColliderComponent);
collider.shape = new SphereColliderShape(1);
this.view.scene.addChild(sphereObj);
}
private loop() {
if (Physics.isInited) {
//get ammo world collision info
this.dispatcher = this.ammoWorld.getDispatcher();
//get count of collision info
this.numManifolds = this.dispatcher.getNumManifolds();
if (this.numManifolds > 0) {
//iterate all collision info
for (let index = 0; index < this.numManifolds; index++) {
this.Manifold = this.dispatcher.getManifoldByIndexInternal(index);
//detect ammo rigidbody's userindex,if greater than -1,the box(food) is colliding
if (this.Manifold.getBody0().getUserIndex() > -1 || this.Manifold.getBody1().getUserIndex() > -1) {
this.objIndex = Math.max(this.Manifold.getBody0().getUserIndex(), this.Manifold.getBody1().getUserIndex());
//destroy this box
this.tempObj = this.foods[this.objIndex];
if (this.tempObj) {
this.foods[this.objIndex] = undefined;
this.score++;
this.tempObj.destroy();
}
}
}
}
Physics.update();
}
}
}

class MoveScript extends ComponentBase {
forward: boolean = false;
back: boolean = false;
left: boolean = false;
right: boolean = false;
moveSpeed: number = 30;
rigidbody: Rigidbody;
x: number = 0;
y: number = 0;
direction: Vector3 = new Vector3();
init(): void {
Engine3D.inputSystem.addEventListener(KeyEvent.KEY_DOWN, this.keyDown, this);
Engine3D.inputSystem.addEventListener(KeyEvent.KEY_UP, this.keyUp, this);
}
private keyDown(e: KeyEvent) {
if (e.keyCode == KeyCode.Key_A) {
this.left = true;
}
else if (e.keyCode == KeyCode.Key_D) {
this.right = true;
}
else if (e.keyCode == KeyCode.Key_W) {
this.forward = true;
}
else if (e.keyCode == KeyCode.Key_S) {
this.back = true;
}
}
private keyUp(e: KeyEvent) {
if (e.keyCode == KeyCode.Key_A) {
this.left = false;
}
else if (e.keyCode == KeyCode.Key_D) {
this.right = false;
}
else if (e.keyCode == KeyCode.Key_W) {
this.forward = false;
}
else if (e.keyCode == KeyCode.Key_S) {
this.back = false;
}
}

onUpdate() {
//if w or a or s or d was pressed
if (this.forward || this.back || this.left || this.right) {
//activate ammo btrigidbody if its state is inactive
if (!this.rigidbody.btRigidbody.isActive()) {
this.rigidbody.btRigidbody.activate();
}
//force the ball to move
this.x = -1 * Number(this.left) + Number(this.right);
this.y = -1 * Number(this.forward) + Number(this.back);
this.direction.set(this.x * this.moveSpeed * Time.delta, 0, this.y * this.moveSpeed * Time.delta);
this.rigidbody.velocity = this.direction;
}
}
}
//rotate script
class RotateScript extends ComponentBase {
onUpdate() {
this.object3D.rotationY += 90 * Time.delta / 1000;
}
}

new Sample_EatTheBox().run();
Loading
Loading