Updated soccer menu....moved soccer specific code to soccer.
This commit is contained in:
parent
18adccc77e
commit
7cfe2fe257
@ -1,4 +1,4 @@
|
||||
import {AbstractMesh, Observable, TransformNode, Vector3} from "@babylonjs/core";
|
||||
import {AbstractMesh, Observable, TransformNode, Vector3, WebXRInputSource} from "@babylonjs/core";
|
||||
|
||||
export type ControllerEvent = {
|
||||
type: ControllerEventType,
|
||||
@ -7,6 +7,7 @@ export type ControllerEvent = {
|
||||
endPosition?: Vector3,
|
||||
duration?: number,
|
||||
gripId?: string;
|
||||
controller?: WebXRInputSource;
|
||||
}
|
||||
|
||||
export enum ControllerEventType {
|
||||
|
||||
@ -27,6 +27,7 @@ export class Left extends Base {
|
||||
});
|
||||
this.initXButton(init.components['x-button']);
|
||||
this.initYButton(init.components['y-button']);
|
||||
this.initTrigger(init.components['xr-standard-trigger']);
|
||||
init.components['xr-standard-thumbstick'].onButtonStateChangedObservable.add((value) => {
|
||||
if (value.pressed) {
|
||||
log.trace('Left', 'thumbstick changed');
|
||||
@ -40,6 +41,21 @@ export class Left extends Base {
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private initTrigger(trigger: WebXRControllerComponent) {
|
||||
if (trigger) {
|
||||
trigger
|
||||
.onButtonStateChangedObservable
|
||||
.add((button) => {
|
||||
this.controllers.controllerObserver.notifyObservers({
|
||||
type: ControllerEventType.TRIGGER,
|
||||
value: button.value,
|
||||
controller: this.controller
|
||||
});
|
||||
}, -1, false, this);
|
||||
}
|
||||
}
|
||||
|
||||
private initXButton(xbutton: WebXRControllerComponent) {
|
||||
if (xbutton) {
|
||||
xbutton.onButtonStateChangedObservable.add((button) => {
|
||||
|
||||
@ -22,6 +22,7 @@ export class Right extends Base {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private startTime: number = null;
|
||||
private endPosition: Vector3 = null;
|
||||
|
||||
@ -46,32 +47,11 @@ export class Right extends Base {
|
||||
trigger
|
||||
.onButtonStateChangedObservable
|
||||
.add((button) => {
|
||||
if (button.pressed) {
|
||||
this.controllers.controllerObserver.notifyObservers({
|
||||
type: ControllerEventType.TRIGGER,
|
||||
value: button.value
|
||||
});
|
||||
if (!this.startTime) {
|
||||
this.startTime = new Date().getTime();
|
||||
this.startPosition = this.controller.pointer.absolutePosition.clone();
|
||||
}
|
||||
|
||||
} else {
|
||||
this.endPosition = this.controller.pointer.absolutePosition.clone();
|
||||
if (this.startTime && this.startPosition) {
|
||||
const duration = new Date().getTime() - this.startTime;
|
||||
|
||||
this.controllers.controllerObserver.notifyObservers({
|
||||
type: ControllerEventType.MOTION,
|
||||
startPosition: this.startPosition,
|
||||
endPosition: this.endPosition,
|
||||
duration: duration
|
||||
});
|
||||
this.startTime = null;
|
||||
this.startPosition = null;
|
||||
}
|
||||
|
||||
}
|
||||
this.controllers.controllerObserver.notifyObservers({
|
||||
type: ControllerEventType.TRIGGER,
|
||||
value: button.value,
|
||||
controller: this.controller
|
||||
});
|
||||
}, -1, false, this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {Angle, Color3, Mesh, MeshBuilder, Quaternion, Scene, Vector3, WebXRDefaultExperience} from "@babylonjs/core";
|
||||
import {Angle, Mesh, Quaternion, Scene, Vector3, WebXRDefaultExperience} from "@babylonjs/core";
|
||||
import {Right} from "./right";
|
||||
import {Left} from "./left";
|
||||
import {EditMenu} from "../menus/editMenu";
|
||||
@ -124,45 +124,16 @@ export class Rigplatform {
|
||||
case ControllerEventType.MENU:
|
||||
this.bMenu.toggle();
|
||||
break;
|
||||
case ControllerEventType.TRIGGER:
|
||||
const worldRay = this.scene.activeCamera.getForwardRay();
|
||||
worldRay.origin = this.scene.activeCamera.globalPosition;
|
||||
const pickInfo = this.scene.pickWithRay(worldRay, null);
|
||||
if (pickInfo?.hit) {
|
||||
const circle = MeshBuilder.CreateSphere("circle", {diameter: .02}, this.scene);
|
||||
circle.position = pickInfo.pickedPoint;
|
||||
setTimeout(() => {
|
||||
circle.dispose();
|
||||
}, 500);
|
||||
|
||||
if (pickInfo?.pickedMesh?.name == 'Football Ball.001') {
|
||||
this.controllers.controllerObserver.notifyObservers({
|
||||
type: ControllerEventType.GAZEPOINT,
|
||||
endPosition: pickInfo.pickedPoint,
|
||||
startPosition: this.xr.baseExperience.camera.globalPosition
|
||||
})
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ControllerEventType.MOTION:
|
||||
this.logger.debug(JSON.stringify(event));
|
||||
this.buildKickLine(event.startPosition, event.endPosition);
|
||||
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private buildKickLine(start: Vector3, end: Vector3) {
|
||||
if (end.y < start.y) {
|
||||
const line = MeshBuilder.CreateLines("kickLine", {points: [start, end]}, this.scene);
|
||||
line.color = new Color3(1, 0, 0);
|
||||
line.isPickable = false;
|
||||
setTimeout(() => {
|
||||
line.dispose();
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
private initializeControllers() {
|
||||
this.xr.input.onControllerAddedObservable.add((source) => {
|
||||
|
||||
@ -16,7 +16,7 @@ export class Ball {
|
||||
private readonly scene: Scene;
|
||||
private transformNode: TransformNode;
|
||||
private mesh: AbstractMesh;
|
||||
private position: Vector3 = new Vector3(0, .5, 0);
|
||||
_position: Vector3 = new Vector3(0, .5, 0);
|
||||
private parent: AbstractMesh;
|
||||
private controllers: Controllers;
|
||||
private physicsAggregate: PhysicsAggregate;
|
||||
@ -39,6 +39,10 @@ export class Ball {
|
||||
this.physicsAggregate.body.applyImpulse(direction.scale(force), Vector3.Zero());
|
||||
}
|
||||
|
||||
public get position(): Vector3 {
|
||||
return this.physicsAggregate.transformNode.absolutePosition;
|
||||
}
|
||||
|
||||
private buildBall() {
|
||||
SceneLoader.ImportMesh(null, "/assets/models/", "ball.gltf", this.scene,
|
||||
(meshes, particleSystems, skeletons, animationGroups) => {
|
||||
@ -47,7 +51,7 @@ export class Ball {
|
||||
this.parent = MeshBuilder.CreateSphere("ballParent", {diameter: .17}, this.scene);
|
||||
|
||||
this.parent.isVisible = false;
|
||||
this.parent.position = this.position;
|
||||
this.parent.position = this._position;
|
||||
|
||||
this.scene.onBeforeRenderObservable.add(() => {
|
||||
if (!this.physicsAggregate &&
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import {Scene, WebXRDefaultExperience} from "@babylonjs/core";
|
||||
import {Color3, MeshBuilder, Quaternion, Scene, Vector3, WebXRDefaultExperience} from "@babylonjs/core";
|
||||
import {AbstractMenu} from "../menus/abstractMenu";
|
||||
import {ControllerEventType, Controllers} from "../controllers/controllers";
|
||||
import {ControllerEvent, ControllerEventType, Controllers} from "../controllers/controllers";
|
||||
import {GUI3DManager, PlanePanel} from "@babylonjs/gui";
|
||||
import log, {Logger} from "loglevel";
|
||||
import {Field} from "./field";
|
||||
import {getFrontPosition} from "../util/functions/getFrontPosition";
|
||||
|
||||
enum SoccerMenuState {
|
||||
PLAY,
|
||||
@ -18,29 +19,114 @@ export class SoccerMenu extends AbstractMenu {
|
||||
private state: SoccerMenuState = SoccerMenuState.NONE;
|
||||
private readonly field: Field;
|
||||
private logger: Logger = log.getLogger('SoccerMenu')
|
||||
private startTime: number;
|
||||
private startPosition: Vector3;
|
||||
|
||||
constructor(scene: Scene, xr: WebXRDefaultExperience, controllers: Controllers) {
|
||||
super(scene, xr, controllers);
|
||||
this.field = new Field(this.scene);
|
||||
this.manager = new GUI3DManager(this.scene);
|
||||
|
||||
this.controllers.controllerObserver.add((event) => {
|
||||
switch (event.type) {
|
||||
case ControllerEventType.MOTION:
|
||||
this.field.ball.kick(event.startPosition.clone().subtract(event.endPosition).normalize(), event.duration / 100);
|
||||
break;
|
||||
case ControllerEventType.GAZEPOINT:
|
||||
if (event.endPosition) {
|
||||
this.field.gazePoint = event.endPosition.clone();
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
this.controllers.controllerObserver.add(this.controllerEventHandler, -1, false, this);
|
||||
this.buildMenu();
|
||||
}
|
||||
|
||||
private controllerEventHandler(event: ControllerEvent) {
|
||||
switch (this.state) {
|
||||
case SoccerMenuState.PLAY:
|
||||
this.playControllerEventHandler(event);
|
||||
break;
|
||||
case SoccerMenuState.PLAN:
|
||||
break;
|
||||
case SoccerMenuState.TRAIN:
|
||||
break;
|
||||
case SoccerMenuState.NONE:
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private playControllerEventHandler(event: ControllerEvent) {
|
||||
switch (event.type) {
|
||||
case ControllerEventType.TRIGGER:
|
||||
if (event.value > .8) {
|
||||
if (!this.startTime) {
|
||||
this.startTime = new Date().getTime();
|
||||
this.startPosition = event.controller.pointer.position.clone();
|
||||
}
|
||||
} else {
|
||||
if (this.startTime) {
|
||||
const endPosition = event.controller.pointer.position.clone();
|
||||
if (this.startTime && this.startPosition) {
|
||||
const duration = new Date().getTime() - this.startTime;
|
||||
|
||||
this.controllers.controllerObserver.notifyObservers({
|
||||
type: ControllerEventType.MOTION,
|
||||
startPosition: this.startPosition,
|
||||
endPosition: endPosition,
|
||||
duration: duration
|
||||
});
|
||||
this.startTime = null;
|
||||
this.startPosition = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
const worldRay = this.scene.activeCamera.getForwardRay();
|
||||
worldRay.origin = this.scene.activeCamera.globalPosition;
|
||||
const pickInfo = this.scene.pickWithRay(worldRay, null);
|
||||
if (pickInfo?.hit) {
|
||||
const circle = MeshBuilder.CreateSphere("circle", {diameter: .04}, this.scene);
|
||||
circle.position = pickInfo.pickedPoint;
|
||||
setTimeout(() => {
|
||||
circle.dispose();
|
||||
}, 1500);
|
||||
|
||||
if (pickInfo?.pickedMesh?.name == 'Football Ball.001') {
|
||||
this.controllers.controllerObserver.notifyObservers({
|
||||
type: ControllerEventType.GAZEPOINT,
|
||||
endPosition: pickInfo.pickedPoint,
|
||||
startPosition: this.xr.baseExperience.camera.globalPosition
|
||||
})
|
||||
}
|
||||
}
|
||||
const mesh = this.scene.getPointerOverMesh();
|
||||
if (mesh) {
|
||||
const meta = mesh?.parent?.parent?.parent
|
||||
if (meta) {
|
||||
console.log(meta.id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ControllerEventType.MOTION:
|
||||
const start = event.startPosition.clone();
|
||||
const direction = start.subtract(event.endPosition);
|
||||
const force = direction.length() * 10;
|
||||
const dir = direction.normalize();
|
||||
const e = this.xr.baseExperience.camera.absoluteRotation.toEulerAngles();
|
||||
direction.applyRotationQuaternionInPlace(Quaternion.FromEulerAngles(0, e.y, 0));
|
||||
|
||||
this.buildKickLine(dir, force);
|
||||
this.field.ball.kick(dir, force);
|
||||
break;
|
||||
case ControllerEventType.GAZEPOINT:
|
||||
if (event.endPosition) {
|
||||
this.field.gazePoint = event.endPosition.clone();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private buildKickLine(direction: Vector3, force: number) {
|
||||
const start = this.field.ball.position.clone();
|
||||
const line = MeshBuilder.CreateLines("kickLine", {points: [start, start.add(direction.scale(force))]}, this.scene);
|
||||
line.color = new Color3(1, 1, .5);
|
||||
line.isPickable = false;
|
||||
setTimeout(() => {
|
||||
line.dispose();
|
||||
}, 2000);
|
||||
|
||||
}
|
||||
|
||||
makeButton(name: string, id: string) {
|
||||
const button = super.makeButton(name, id);
|
||||
button.onPointerClickObservable.add(this.handleClick, -1, false, this);
|
||||
@ -56,7 +142,9 @@ export class SoccerMenu extends AbstractMenu {
|
||||
panel.addControl(this.makeButton("Train", "Train"));
|
||||
panel.addControl(this.makeButton("Modify", "modify"));
|
||||
this.manager.rootContainer.children[0].node.position.y = .2;
|
||||
this.manager.controlScaling = .2;
|
||||
this.createHandle(this.manager.rootContainer.children[0].node);
|
||||
this.handle.mesh.position = getFrontPosition(3, this.scene).add(new Vector3(0, .5, 0));
|
||||
}
|
||||
|
||||
private handleClick(_info, state) {
|
||||
|
||||
@ -29,7 +29,6 @@ export class Team {
|
||||
this.playerFactory = new PlayerFactory(this.scene);
|
||||
this.playerFactory.onReadyObservable.add(() => {
|
||||
this.buildTeam();
|
||||
this.players[5].runTo(new Vector2(3, -3 * this.goalSide));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user