@gg-web-engine/core 0.0.24 → 0.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/2d/components/physics/i-rigid-body-2d.component.d.ts +1 -0
- package/dist/2d/gg-2d-world.d.ts +1 -2
- package/dist/2d/gg-2d-world.js +4 -5
- package/dist/3d/components/physics/i-raycast-vehicle.component.d.ts +3 -6
- package/dist/3d/components/physics/i-rigid-body-3d.component.d.ts +1 -0
- package/dist/3d/entities/controllers/input/car-keyboard-handling.controller.d.ts +11 -13
- package/dist/3d/entities/controllers/input/car-keyboard-handling.controller.js +29 -72
- package/dist/3d/entities/controllers/input/gg-car-keyboard-handling.controller.d.ts +18 -0
- package/dist/3d/entities/controllers/input/gg-car-keyboard-handling.controller.js +96 -0
- package/dist/3d/entities/gg-car/gg-car.entity.d.ts +79 -0
- package/dist/3d/entities/gg-car/gg-car.entity.js +228 -0
- package/dist/3d/entities/raycast-vehicle-3d.entity.d.ts +43 -76
- package/dist/3d/entities/raycast-vehicle-3d.entity.js +78 -299
- package/dist/3d/gg-3d-world.d.ts +1 -2
- package/dist/3d/gg-3d-world.js +4 -5
- package/dist/3d/index.d.ts +2 -0
- package/dist/3d/index.js +2 -0
- package/dist/base/components/physics/i-body.component.d.ts +14 -0
- package/dist/base/components/physics/i-body.component.js +1 -0
- package/dist/base/components/physics/i-rigid-body.component.d.ts +4 -11
- package/dist/base/components/physics/i-trigger.component.d.ts +3 -1
- package/dist/base/entities/i-entity.js +1 -1
- package/dist/base/gg-world.d.ts +8 -12
- package/dist/base/gg-world.js +32 -64
- package/dist/base/index.d.ts +2 -3
- package/dist/base/index.js +2 -3
- package/dist/base/math/point2.d.ts +4 -0
- package/dist/base/math/point2.js +8 -0
- package/dist/base/math/point3.d.ts +6 -0
- package/dist/base/math/point3.js +12 -0
- package/dist/base/math/splines.d.ts +1 -0
- package/dist/base/math/splines.js +7 -0
- package/dist/{base/ui → dev}/gg-console.ui.d.ts +1 -4
- package/dist/{base/ui → dev}/gg-console.ui.js +35 -17
- package/dist/dev/gg-debugger.ui.d.ts +11 -0
- package/dist/dev/gg-debugger.ui.js +111 -0
- package/dist/dev/gg-static.d.ts +32 -0
- package/dist/dev/gg-static.js +141 -0
- package/dist/dev/index.d.ts +3 -0
- package/dist/dev/index.js +3 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
- package/dist/base/gg-static.d.ts +0 -9
- package/dist/base/gg-static.js +0 -36
- package/dist/base/ui/gg-debugger.ui.d.ts +0 -10
- package/dist/base/ui/gg-debugger.ui.js +0 -61
|
@@ -1,99 +1,66 @@
|
|
|
1
1
|
import { AxisDirection3, IEntity, Point3, Point4 } from '../../base';
|
|
2
2
|
import { Entity3d } from './entity-3d';
|
|
3
|
-
import { BehaviorSubject, Observable } from 'rxjs';
|
|
4
|
-
import { Gg3dWorld } from '../gg-3d-world';
|
|
5
3
|
import { IDisplayObject3dComponent } from '../components/rendering/i-display-object-3d.component';
|
|
6
|
-
import { IRaycastVehicleComponent, SuspensionOptions
|
|
4
|
+
import { IRaycastVehicleComponent, SuspensionOptions } from '../components/physics/i-raycast-vehicle.component';
|
|
7
5
|
import { IRigidBody3dComponent } from '../components/physics/i-rigid-body-3d.component';
|
|
8
6
|
import { IPositionable3d } from '../interfaces/i-positionable-3d';
|
|
9
|
-
export declare type
|
|
7
|
+
export declare type WheelDisplayOptions = {
|
|
8
|
+
displayObject?: IDisplayObject3dComponent;
|
|
9
|
+
wheelObjectDirection?: AxisDirection3;
|
|
10
|
+
autoScaleMesh?: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare type RVEntitySharedWheelOptions = {
|
|
13
|
+
tyreWidth?: number;
|
|
14
|
+
tyreRadius?: number;
|
|
15
|
+
frictionSlip?: number;
|
|
16
|
+
rollInfluence?: number;
|
|
17
|
+
maxTravel?: number;
|
|
18
|
+
display?: WheelDisplayOptions;
|
|
19
|
+
};
|
|
20
|
+
export declare type RVEntityAxleOptions = {
|
|
21
|
+
halfAxleWidth: number;
|
|
22
|
+
axlePosition: number;
|
|
23
|
+
axleHeight: number;
|
|
24
|
+
} & RVEntitySharedWheelOptions;
|
|
25
|
+
export declare type RVEntityProperties = {
|
|
10
26
|
typeOfDrive: 'RWD' | 'FWD' | '4WD';
|
|
11
|
-
wheelOptions: WheelOptions[];
|
|
12
|
-
mpsToRpmFactor?: number;
|
|
13
|
-
engine: {
|
|
14
|
-
minRpm: number;
|
|
15
|
-
maxRpm: number;
|
|
16
|
-
torques: {
|
|
17
|
-
rpm: number;
|
|
18
|
-
torque: number;
|
|
19
|
-
}[];
|
|
20
|
-
maxRpmIncreasePerSecond: number;
|
|
21
|
-
maxRpmDecreasePerSecond: number;
|
|
22
|
-
};
|
|
23
|
-
brake: {
|
|
24
|
-
frontAxleForce: number;
|
|
25
|
-
rearAxleForce: number;
|
|
26
|
-
handbrakeForce: number;
|
|
27
|
-
};
|
|
28
|
-
transmission: {
|
|
29
|
-
isAuto: boolean;
|
|
30
|
-
reverseGearRatio: number;
|
|
31
|
-
gearRatios: number[];
|
|
32
|
-
drivelineEfficiency: number;
|
|
33
|
-
finalDriveRatio: number;
|
|
34
|
-
upShifts: number[];
|
|
35
|
-
};
|
|
36
27
|
suspension: SuspensionOptions;
|
|
37
|
-
}
|
|
28
|
+
} & ({
|
|
29
|
+
wheelBase: {
|
|
30
|
+
shared: RVEntitySharedWheelOptions;
|
|
31
|
+
front: RVEntityAxleOptions;
|
|
32
|
+
rear: RVEntityAxleOptions;
|
|
33
|
+
};
|
|
34
|
+
} | {
|
|
35
|
+
wheelOptions: (RVEntitySharedWheelOptions & {
|
|
36
|
+
isLeft: boolean;
|
|
37
|
+
isFront: boolean;
|
|
38
|
+
position: Point3;
|
|
39
|
+
})[];
|
|
40
|
+
sharedWheelOptions?: RVEntitySharedWheelOptions;
|
|
41
|
+
});
|
|
38
42
|
export declare class RaycastVehicle3dEntity extends Entity3d {
|
|
39
|
-
readonly carProperties:
|
|
43
|
+
readonly carProperties: RVEntityProperties;
|
|
40
44
|
readonly chassis3D: IDisplayObject3dComponent | null;
|
|
41
45
|
readonly chassisBody: IRaycastVehicleComponent;
|
|
42
|
-
readonly wheelObject: IDisplayObject3dComponent | null;
|
|
43
|
-
readonly wheelObjectDirection: AxisDirection3;
|
|
44
46
|
protected readonly wheels: ((IEntity & IPositionable3d) | null)[];
|
|
45
47
|
protected readonly wheelLocalRotation: (Point4 | null)[];
|
|
46
|
-
protected readonly wheelLocalTranslation: Point3[];
|
|
47
48
|
protected readonly frontWheelsIndices: number[];
|
|
48
49
|
protected readonly rearWheelsIndices: number[];
|
|
49
50
|
protected readonly tractionWheelIndices: number[];
|
|
50
|
-
readonly tractionWheelRadius: number;
|
|
51
|
-
protected get dynamicTractionWheelRadius(): number;
|
|
52
|
-
get engineTorque(): number;
|
|
53
|
-
get transmissionGearRatio(): number;
|
|
54
|
-
protected get mpsToRpm(): number;
|
|
55
51
|
getSpeed(): number;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
private readonly _maxSteerVal;
|
|
63
|
-
get maxSteerVal(): number;
|
|
64
|
-
private getMaxStableSteerVal;
|
|
65
|
-
private _tailLightsOn;
|
|
66
|
-
get tailLightsOn(): boolean;
|
|
67
|
-
protected setTailLightsOn(value: boolean): void;
|
|
68
|
-
protected _acceleration$: BehaviorSubject<number>;
|
|
69
|
-
protected get acceleration(): number;
|
|
70
|
-
get acceleration$(): Observable<number>;
|
|
71
|
-
protected set acceleration(value: number);
|
|
72
|
-
protected brake$: BehaviorSubject<number>;
|
|
73
|
-
protected get brake(): number;
|
|
74
|
-
protected set brake(value: number);
|
|
75
|
-
protected handBrake$: BehaviorSubject<boolean>;
|
|
76
|
-
get handBrake(): boolean;
|
|
77
|
-
set handBrake(value: boolean);
|
|
78
|
-
private _gear;
|
|
79
|
-
private _gear$;
|
|
80
|
-
get gear(): number;
|
|
81
|
-
get gear$(): Observable<number>;
|
|
82
|
-
set gear(value: number);
|
|
83
|
-
set isHonking(value: boolean);
|
|
84
|
-
private _steeringValue;
|
|
85
|
-
get steeringValue(): number;
|
|
86
|
-
protected setSteeringValue(value: number): void;
|
|
52
|
+
readonly tractionWheelRadius: number;
|
|
53
|
+
private _steeringAngle;
|
|
54
|
+
get steeringAngle(): number;
|
|
55
|
+
set steeringAngle(value: number);
|
|
56
|
+
applyTractionForce(force: number): void;
|
|
57
|
+
applyBrake(axle: 'front' | 'rear' | 'both', force: number): void;
|
|
87
58
|
/** car mesh and physics body direction has to be pointing: y front, z up*/
|
|
88
|
-
constructor(carProperties:
|
|
89
|
-
onSpawned(world: Gg3dWorld): void;
|
|
59
|
+
constructor(carProperties: RVEntityProperties, chassis3D: IDisplayObject3dComponent | null, chassisBody: IRaycastVehicleComponent);
|
|
90
60
|
protected runTransformBinding(objectBody: IRigidBody3dComponent, object3D: IDisplayObject3dComponent): void;
|
|
91
|
-
|
|
92
|
-
protected updateEngine(delta: number): void;
|
|
61
|
+
get isTouchingGround(): boolean;
|
|
93
62
|
resetTo(options?: {
|
|
94
63
|
position?: Point3;
|
|
95
64
|
rotation?: Point4;
|
|
96
65
|
}): void;
|
|
97
|
-
setXAxisControlValue(value: number): void;
|
|
98
|
-
setYAxisControlValue(value: number): void;
|
|
99
66
|
}
|
|
@@ -1,300 +1,125 @@
|
|
|
1
1
|
import { Box, Pnt3, Qtrn } from '../../base';
|
|
2
2
|
import { Entity3d } from './entity-3d';
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
const wheeelDefaults = {
|
|
4
|
+
tyreWidth: 0.3,
|
|
5
|
+
tyreRadius: 0.4,
|
|
6
|
+
frictionSlip: 1000,
|
|
7
|
+
rollInfluence: 0.2,
|
|
8
|
+
maxTravel: 0.5,
|
|
9
|
+
};
|
|
5
10
|
export class RaycastVehicle3dEntity extends Entity3d {
|
|
6
11
|
/** car mesh and physics body direction has to be pointing: y front, z up*/
|
|
7
|
-
constructor(carProperties, chassis3D, chassisBody
|
|
12
|
+
constructor(carProperties, chassis3D, chassisBody) {
|
|
8
13
|
super(chassis3D, chassisBody);
|
|
9
14
|
this.carProperties = carProperties;
|
|
10
15
|
this.chassis3D = chassis3D;
|
|
11
16
|
this.chassisBody = chassisBody;
|
|
12
|
-
this.wheelObject = wheelObject;
|
|
13
|
-
this.wheelObjectDirection = wheelObjectDirection;
|
|
14
17
|
this.wheels = [];
|
|
15
18
|
this.wheelLocalRotation = [];
|
|
16
|
-
this.wheelLocalTranslation = [];
|
|
17
19
|
this.frontWheelsIndices = [];
|
|
18
20
|
this.rearWheelsIndices = [];
|
|
19
21
|
this.tractionWheelIndices = [];
|
|
20
|
-
this.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
22
|
+
this._steeringAngle = 0;
|
|
23
|
+
let wheelFullOptions = 'wheelBase' in carProperties
|
|
24
|
+
? [
|
|
25
|
+
carProperties.wheelBase.front,
|
|
26
|
+
carProperties.wheelBase.front,
|
|
27
|
+
carProperties.wheelBase.rear,
|
|
28
|
+
carProperties.wheelBase.rear,
|
|
29
|
+
].map((a, i) => {
|
|
30
|
+
var _a;
|
|
31
|
+
return (Object.assign(Object.assign(Object.assign(Object.assign({}, wheeelDefaults), (carProperties.wheelBase.shared || {})), a), { isFront: i < 2, isLeft: i % 2 === 0, position: {
|
|
32
|
+
x: a.halfAxleWidth * (i % 2 === 0 ? 1 : -1),
|
|
33
|
+
y: a.axlePosition,
|
|
34
|
+
z: a.axleHeight,
|
|
35
|
+
}, display: Object.assign(Object.assign({}, (((_a = carProperties.wheelBase.shared) === null || _a === void 0 ? void 0 : _a.display) || {})), (a.display || {})) }));
|
|
36
|
+
})
|
|
37
|
+
: carProperties.wheelOptions.map((x, i) => {
|
|
38
|
+
var _a;
|
|
39
|
+
return (Object.assign(Object.assign(Object.assign(Object.assign({}, wheeelDefaults), (carProperties.sharedWheelOptions || {})), x), { display: Object.assign(Object.assign({}, (((_a = carProperties.sharedWheelOptions) === null || _a === void 0 ? void 0 : _a.display) || {})), (x.display || {})) }));
|
|
40
|
+
});
|
|
41
|
+
// TODO perform this in a parent application
|
|
42
|
+
// chassisBody.setDamping(0.02, 0.02); // TODO imitates air resistance. calculate from properties
|
|
43
|
+
wheelFullOptions.forEach((wheelOpts, i) => {
|
|
44
|
+
if (wheelOpts.isFront) {
|
|
34
45
|
this.frontWheelsIndices.push(i);
|
|
35
46
|
}
|
|
36
47
|
else {
|
|
37
48
|
this.rearWheelsIndices.push(i);
|
|
38
49
|
}
|
|
39
|
-
if (
|
|
50
|
+
if (wheelOpts.isFront && this.carProperties.typeOfDrive != 'RWD') {
|
|
40
51
|
this.tractionWheelIndices.push(i);
|
|
41
52
|
}
|
|
42
|
-
if (!
|
|
53
|
+
if (!wheelOpts.isFront && this.carProperties.typeOfDrive != 'FWD') {
|
|
43
54
|
this.tractionWheelIndices.push(i);
|
|
44
55
|
}
|
|
45
|
-
});
|
|
46
|
-
this.tractionWheelRadius = this.carProperties.wheelOptions[this.tractionWheelIndices[0]].tyre_radius;
|
|
47
|
-
// TODO perform this in a parent application
|
|
48
|
-
// chassisBody.setDamping(0.02, 0.02); // TODO imitates air resistance. calculate from properties
|
|
49
|
-
this.carProperties.wheelOptions.forEach(wheelOpts => {
|
|
50
56
|
this.chassisBody.addWheel(wheelOpts, this.carProperties.suspension);
|
|
51
57
|
});
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
this.tractionWheelRadius = wheelFullOptions[this.tractionWheelIndices[0]].tyreRadius;
|
|
59
|
+
for (const options of wheelFullOptions) {
|
|
60
|
+
const display = options.display || {};
|
|
61
|
+
if (!display.displayObject) {
|
|
62
|
+
this.wheels.push(null);
|
|
63
|
+
this.wheelLocalRotation.push(null);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const entity = display.displayObject.clone();
|
|
67
|
+
if (display.autoScaleMesh) {
|
|
62
68
|
const boundingBox = Box.expandByPoint(entity.getBoundings(), Pnt3.O);
|
|
63
69
|
const scale = Object.assign({}, Pnt3.O);
|
|
70
|
+
const wheelObjectDirection = display.wheelObjectDirection || 'x';
|
|
64
71
|
for (const dir of ['x', 'y', 'z']) {
|
|
65
|
-
const wheelObjectDirection = options.wheelObjectDirection || this.wheelObjectDirection;
|
|
66
72
|
const isNormal = wheelObjectDirection.includes(dir);
|
|
67
73
|
scale[dir] = isNormal
|
|
68
|
-
? options.
|
|
69
|
-
: (options.
|
|
70
|
-
if (isNormal) {
|
|
71
|
-
localTranslation.x +=
|
|
72
|
-
(wheelObjectDirection.startsWith('-') ? boundingBox.max[dir] : boundingBox.min[dir]) *
|
|
73
|
-
scale[dir] *
|
|
74
|
-
(options.isLeft ? 1 : -1);
|
|
75
|
-
}
|
|
74
|
+
? options.tyreWidth / (boundingBox.max[dir] - boundingBox.min[dir])
|
|
75
|
+
: (options.tyreRadius * 2) / (boundingBox.max[dir] - boundingBox.min[dir]);
|
|
76
76
|
}
|
|
77
77
|
entity.scale = scale;
|
|
78
|
-
const direction = options.wheelObjectDirection || this.wheelObjectDirection;
|
|
79
|
-
const flip = direction.includes('-') ? !options.isLeft : options.isLeft;
|
|
80
|
-
let localRotation = null;
|
|
81
|
-
if (direction.includes('x')) {
|
|
82
|
-
// rotate PI around Z if opposite position (x is correct for right wheel, -x is correct for left wheel)
|
|
83
|
-
if (flip)
|
|
84
|
-
localRotation = { x: 0, y: 0, z: 1, w: 0 };
|
|
85
|
-
}
|
|
86
|
-
else if (direction.includes('y')) {
|
|
87
|
-
// rotate PI/2 around Z
|
|
88
|
-
localRotation = { x: 0, y: 0, z: 0.707107 * (flip ? 1 : -1), w: 0.707107 };
|
|
89
|
-
}
|
|
90
|
-
else if (direction.includes('z')) {
|
|
91
|
-
// rotate PI/2 around Y
|
|
92
|
-
localRotation = { x: 0, y: 0.707107 * (flip ? -1 : 1), z: 0, w: 0.707107 };
|
|
93
|
-
}
|
|
94
|
-
this.wheelLocalTranslation.push(localTranslation);
|
|
95
|
-
this.wheelLocalRotation.push(localRotation);
|
|
96
|
-
this.wheels.push(new Entity3d(entity));
|
|
97
78
|
}
|
|
79
|
+
const direction = display.wheelObjectDirection || 'x';
|
|
80
|
+
const flip = direction.includes('-') ? !options.isLeft : options.isLeft;
|
|
81
|
+
let localRotation = null;
|
|
82
|
+
if (direction.includes('x')) {
|
|
83
|
+
// rotate PI around Z if opposite position (x is correct for right wheel, -x is correct for left wheel)
|
|
84
|
+
if (flip)
|
|
85
|
+
localRotation = { x: 0, y: 0, z: 1, w: 0 };
|
|
86
|
+
}
|
|
87
|
+
else if (direction.includes('y')) {
|
|
88
|
+
// rotate PI/2 around Z
|
|
89
|
+
localRotation = { x: 0, y: 0, z: 0.707107 * (flip ? 1 : -1), w: 0.707107 };
|
|
90
|
+
}
|
|
91
|
+
else if (direction.includes('z')) {
|
|
92
|
+
// rotate PI/2 around Y
|
|
93
|
+
localRotation = { x: 0, y: 0.707107 * (flip ? -1 : 1), z: 0, w: 0.707107 };
|
|
94
|
+
}
|
|
95
|
+
this.wheelLocalRotation.push(localRotation);
|
|
96
|
+
this.wheels.push(new Entity3d(entity));
|
|
98
97
|
}
|
|
99
98
|
this.addChildren(...this.wheels.filter(x => !!x));
|
|
100
99
|
this.chassisBody.entity = this;
|
|
101
100
|
}
|
|
102
|
-
get dynamicTractionWheelRadius() {
|
|
103
|
-
// The dynamic wheel radius [m] is the radius of the wheel when the vehicle is in motion. It is smaller than the static wheel radius rws because the tire is slightly compressed during vehicle motion.
|
|
104
|
-
return 0.98 * this.tractionWheelRadius;
|
|
105
|
-
}
|
|
106
|
-
get engineTorque() {
|
|
107
|
-
const currentRPM = this.engineRpm;
|
|
108
|
-
const maxMapTorque = this.carProperties.engine.torques[this.carProperties.engine.torques.length - 1].rpm;
|
|
109
|
-
if (currentRPM >= maxMapTorque) {
|
|
110
|
-
return (Math.pow(Math.max(0, 1 - (currentRPM - maxMapTorque) / (this.carProperties.engine.maxRpm - maxMapTorque)), 2) *
|
|
111
|
-
this.carProperties.engine.torques[this.carProperties.engine.torques.length - 1].torque);
|
|
112
|
-
}
|
|
113
|
-
let index = 0;
|
|
114
|
-
let factor = 0;
|
|
115
|
-
for (let i = 0; i < this.carProperties.engine.torques.length; i++) {
|
|
116
|
-
if (this.carProperties.engine.torques[i].rpm < currentRPM) {
|
|
117
|
-
index = i;
|
|
118
|
-
continue;
|
|
119
|
-
}
|
|
120
|
-
factor = Math.max(0, (currentRPM - this.carProperties.engine.torques[index].rpm) /
|
|
121
|
-
(this.carProperties.engine.torques[index + 1].rpm - this.carProperties.engine.torques[index].rpm));
|
|
122
|
-
break;
|
|
123
|
-
}
|
|
124
|
-
if (factor === 0) {
|
|
125
|
-
return this.carProperties.engine.torques[index].torque;
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
return (this.carProperties.engine.torques[index].torque +
|
|
129
|
-
factor * (this.carProperties.engine.torques[index + 1].torque - this.carProperties.engine.torques[index].torque));
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
get transmissionGearRatio() {
|
|
133
|
-
if (this._gear == -1) {
|
|
134
|
-
return this.carProperties.transmission.reverseGearRatio;
|
|
135
|
-
}
|
|
136
|
-
return this.carProperties.transmission.gearRatios[this._gear - 1] || 0;
|
|
137
|
-
}
|
|
138
|
-
get mpsToRpm() {
|
|
139
|
-
return (this.carProperties.mpsToRpmFactor ||
|
|
140
|
-
(30 * this.carProperties.transmission.finalDriveRatio) / (Math.PI * this.dynamicTractionWheelRadius));
|
|
141
|
-
}
|
|
142
101
|
// m/s
|
|
143
102
|
getSpeed() {
|
|
144
103
|
return this.chassisBody.wheelSpeed;
|
|
145
104
|
}
|
|
146
|
-
|
|
147
|
-
return this.
|
|
105
|
+
get steeringAngle() {
|
|
106
|
+
return this._steeringAngle;
|
|
148
107
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
return this.getSpeed();
|
|
153
|
-
}
|
|
154
|
-
const kmh = this.getSpeed() * 3.6;
|
|
155
|
-
if (units === 'mph') {
|
|
156
|
-
return kmh * 0.621371192;
|
|
108
|
+
set steeringAngle(value) {
|
|
109
|
+
if (this._steeringAngle != value) {
|
|
110
|
+
this._steeringAngle = value;
|
|
157
111
|
}
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
get engineRpm$() {
|
|
161
|
-
return this._rpm$.asObservable();
|
|
162
|
-
}
|
|
163
|
-
get engineRpm() {
|
|
164
|
-
return this._rpm$.getValue();
|
|
112
|
+
this.frontWheelsIndices.forEach(index => this.chassisBody.setSteering(index, value));
|
|
165
113
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
this.transmissionGearRatio *
|
|
169
|
-
this.carProperties.transmission.finalDriveRatio *
|
|
170
|
-
this.carProperties.transmission.drivelineEfficiency) /
|
|
171
|
-
this.dynamicTractionWheelRadius);
|
|
114
|
+
applyTractionForce(force) {
|
|
115
|
+
this.tractionWheelIndices.forEach(index => this.chassisBody.applyEngineForce(index, force));
|
|
172
116
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
getMaxStableSteerVal() {
|
|
177
|
-
const speed = this.getSpeed() * 3.6;
|
|
178
|
-
if (speed < 40) {
|
|
179
|
-
return this.maxSteerVal;
|
|
117
|
+
applyBrake(axle, force) {
|
|
118
|
+
if (axle != 'rear') {
|
|
119
|
+
this.frontWheelsIndices.forEach(index => this.chassisBody.applyBrake(index, force));
|
|
180
120
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
184
|
-
get tailLightsOn() {
|
|
185
|
-
return this._tailLightsOn;
|
|
186
|
-
}
|
|
187
|
-
setTailLightsOn(value) {
|
|
188
|
-
if (this._tailLightsOn != value) {
|
|
189
|
-
this._tailLightsOn = value;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
get acceleration() {
|
|
193
|
-
return this._acceleration$.getValue();
|
|
194
|
-
}
|
|
195
|
-
get acceleration$() {
|
|
196
|
-
return this._acceleration$.asObservable();
|
|
197
|
-
}
|
|
198
|
-
set acceleration(value) {
|
|
199
|
-
this._acceleration$.next(value);
|
|
200
|
-
}
|
|
201
|
-
get brake() {
|
|
202
|
-
return this.brake$.getValue();
|
|
203
|
-
}
|
|
204
|
-
set brake(value) {
|
|
205
|
-
this.brake$.next(value);
|
|
206
|
-
}
|
|
207
|
-
get handBrake() {
|
|
208
|
-
return this.handBrake$.getValue();
|
|
209
|
-
}
|
|
210
|
-
set handBrake(value) {
|
|
211
|
-
this.handBrake$.next(value);
|
|
212
|
-
}
|
|
213
|
-
get gear() {
|
|
214
|
-
return this._gear;
|
|
215
|
-
}
|
|
216
|
-
get gear$() {
|
|
217
|
-
return this._gear$.asObservable();
|
|
218
|
-
}
|
|
219
|
-
set gear(value) {
|
|
220
|
-
value = Math.max(-1, Math.min(this.carProperties.transmission.gearRatios.length, value));
|
|
221
|
-
if (value === this._gear) {
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
|
-
this._gear = value;
|
|
225
|
-
this._gear$.next(value);
|
|
226
|
-
}
|
|
227
|
-
// TODO remove
|
|
228
|
-
set isHonking(value) { }
|
|
229
|
-
get steeringValue() {
|
|
230
|
-
return this._steeringValue;
|
|
231
|
-
}
|
|
232
|
-
setSteeringValue(value) {
|
|
233
|
-
if (this._steeringValue != value) {
|
|
234
|
-
this._steeringValue = value;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
onSpawned(world) {
|
|
238
|
-
super.onSpawned(world);
|
|
239
|
-
this.tick$.subscribe(([_, delta]) => {
|
|
240
|
-
this.updateEngine(delta);
|
|
241
|
-
if (this.isTouchingGround) {
|
|
242
|
-
// TODO 1 - R (1000 rpm) quick switch with acceleration pedal should have the same speed as without acceleration pedal
|
|
243
|
-
let force = 0;
|
|
244
|
-
let brake = this.brake;
|
|
245
|
-
const calculatedRpm = this.calculateRpmFromCarSpeed();
|
|
246
|
-
if (this.gear !== 0 && calculatedRpm > this.carProperties.engine.maxRpm) {
|
|
247
|
-
// engine brake, this is related to clutch, better clutch condition - bigger force
|
|
248
|
-
force = this.gear > 0 ? -12000 : 12000;
|
|
249
|
-
}
|
|
250
|
-
else {
|
|
251
|
-
force =
|
|
252
|
-
this.acceleration > 0
|
|
253
|
-
? this.tractionForce * this.acceleration // apply torque
|
|
254
|
-
: 0.5 * (this.carProperties.engine.minRpm - calculatedRpm) * (this.gear > 0 ? 1 : -1); // released, use engine brake
|
|
255
|
-
// this functionality makes car stay still (parking gear) when speed is low
|
|
256
|
-
const speedThreshold = 3;
|
|
257
|
-
if (Math.abs(this.getSpeed()) < speedThreshold && (this.gear == 0 || this.acceleration <= 0)) {
|
|
258
|
-
brake = Math.max(brake, (0.3 * (speedThreshold - this.getSpeed())) / speedThreshold);
|
|
259
|
-
force = 0;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
this.tractionWheelIndices.forEach(index => this.chassisBody.applyEngineForce(index, force));
|
|
263
|
-
this.frontWheelsIndices.forEach(index => this.chassisBody.applyBrake(index, brake * this.carProperties.brake.frontAxleForce));
|
|
264
|
-
this.rearWheelsIndices.forEach(index => this.chassisBody.applyBrake(index, brake * this.carProperties.brake.rearAxleForce));
|
|
265
|
-
if (this.handBrake) {
|
|
266
|
-
this.rearWheelsIndices.forEach(index => this.chassisBody.applyBrake(index, this.carProperties.brake.handbrakeForce));
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
});
|
|
270
|
-
if (this.carProperties.transmission.isAuto) {
|
|
271
|
-
this.tick$
|
|
272
|
-
.pipe(throttleTime(50), filter(() => this.isTouchingGround))
|
|
273
|
-
.subscribe(() => {
|
|
274
|
-
let gear = this.gear;
|
|
275
|
-
let upshifted = false;
|
|
276
|
-
if (gear > 0) {
|
|
277
|
-
let rpm = this.engineRpm;
|
|
278
|
-
while (rpm >= this.carProperties.transmission.upShifts[gear - 1]) {
|
|
279
|
-
rpm *=
|
|
280
|
-
this.carProperties.transmission.gearRatios[gear] / this.carProperties.transmission.gearRatios[gear - 1];
|
|
281
|
-
gear++;
|
|
282
|
-
upshifted = true;
|
|
283
|
-
}
|
|
284
|
-
if (!upshifted) {
|
|
285
|
-
while (gear > 1) {
|
|
286
|
-
rpm *=
|
|
287
|
-
this.carProperties.transmission.gearRatios[gear - 2] /
|
|
288
|
-
this.carProperties.transmission.gearRatios[gear - 1];
|
|
289
|
-
if (rpm > this.carProperties.transmission.upShifts[gear - 2]) {
|
|
290
|
-
break;
|
|
291
|
-
}
|
|
292
|
-
gear--;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
this.gear = gear;
|
|
296
|
-
}
|
|
297
|
-
});
|
|
121
|
+
if (axle != 'front') {
|
|
122
|
+
this.rearWheelsIndices.forEach(index => this.chassisBody.applyBrake(index, force));
|
|
298
123
|
}
|
|
299
124
|
}
|
|
300
125
|
runTransformBinding(objectBody, object3D) {
|
|
@@ -308,7 +133,6 @@ export class RaycastVehicle3dEntity extends Entity3d {
|
|
|
308
133
|
if (this.wheelLocalRotation[i]) {
|
|
309
134
|
rotation = Qtrn.combineRotations(rotation, this.wheelLocalRotation[i]);
|
|
310
135
|
}
|
|
311
|
-
position = Pnt3.add(position, Pnt3.rot(this.wheelLocalTranslation[i], carRotation));
|
|
312
136
|
wheel.position = position;
|
|
313
137
|
wheel.rotation = rotation;
|
|
314
138
|
}
|
|
@@ -319,31 +143,6 @@ export class RaycastVehicle3dEntity extends Entity3d {
|
|
|
319
143
|
.map(i => this.chassisBody.isWheelTouchesGround(i))
|
|
320
144
|
.reduce((prev, cur) => cur || prev, false);
|
|
321
145
|
}
|
|
322
|
-
updateEngine(delta) {
|
|
323
|
-
delta = delta / 1000; // ms -> s
|
|
324
|
-
const acceleration = this._acceleration$.getValue();
|
|
325
|
-
let rpm = this.engineRpm;
|
|
326
|
-
// TODO here I will take perioud between gears and drift into account someday :)
|
|
327
|
-
const gripKoeff = this.gear === 0 || !this.isTouchingGround ? 0 : 1;
|
|
328
|
-
if (gripKoeff == 0) {
|
|
329
|
-
rpm +=
|
|
330
|
-
(acceleration * 2 - 1) *
|
|
331
|
-
(acceleration > 0.5
|
|
332
|
-
? this.carProperties.engine.maxRpmIncreasePerSecond
|
|
333
|
-
: this.carProperties.engine.maxRpmDecreasePerSecond) *
|
|
334
|
-
delta;
|
|
335
|
-
}
|
|
336
|
-
else {
|
|
337
|
-
const rpmFromSpeed = this.calculateRpmFromCarSpeed();
|
|
338
|
-
if (rpmFromSpeed > rpm) {
|
|
339
|
-
rpm = Math.min(rpmFromSpeed, rpm + this.carProperties.engine.maxRpmIncreasePerSecond * delta);
|
|
340
|
-
}
|
|
341
|
-
else {
|
|
342
|
-
rpm = Math.max(rpmFromSpeed, rpm - this.carProperties.engine.maxRpmDecreasePerSecond * delta);
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
this._rpm$.next(Math.max(this.carProperties.engine.minRpm, Math.min(this.carProperties.engine.maxRpm, rpm)));
|
|
346
|
-
}
|
|
347
146
|
// TODO delete and let game application do all the steps
|
|
348
147
|
resetTo(options = {}) {
|
|
349
148
|
this.chassisBody.resetMotion();
|
|
@@ -354,26 +153,6 @@ export class RaycastVehicle3dEntity extends Entity3d {
|
|
|
354
153
|
if (options.rotation) {
|
|
355
154
|
this.rotation = options.rotation;
|
|
356
155
|
}
|
|
357
|
-
this.
|
|
358
|
-
this.gear = 0;
|
|
359
|
-
this._rpm$.next(this.carProperties.engine.minRpm);
|
|
360
|
-
}
|
|
361
|
-
// TODO refactor: control has to be in control service, here we receive separately braking, acceleration, steering
|
|
362
|
-
setXAxisControlValue(value) {
|
|
363
|
-
const steering = this.getMaxStableSteerVal() * value;
|
|
364
|
-
this.frontWheelsIndices.forEach(index => this.chassisBody.setSteering(index, -steering));
|
|
365
|
-
this.setSteeringValue(-steering);
|
|
366
|
-
}
|
|
367
|
-
// TODO refactor: control has to be in control service, here we receive separately braking, acceleration, steering
|
|
368
|
-
setYAxisControlValue(value) {
|
|
369
|
-
if (value > 0) {
|
|
370
|
-
this.acceleration = value;
|
|
371
|
-
this.brake = 0;
|
|
372
|
-
}
|
|
373
|
-
else {
|
|
374
|
-
this.acceleration = 0;
|
|
375
|
-
this.brake = -value;
|
|
376
|
-
}
|
|
377
|
-
this.setTailLightsOn(value < 0);
|
|
156
|
+
this.steeringAngle = 0;
|
|
378
157
|
}
|
|
379
158
|
}
|
package/dist/3d/gg-3d-world.d.ts
CHANGED
|
@@ -10,9 +10,8 @@ import { IPhysicsWorld3dComponent } from './components/physics/i-physics-world-3
|
|
|
10
10
|
export declare class Gg3dWorld<V extends IVisualScene3dComponent = IVisualScene3dComponent, P extends IPhysicsWorld3dComponent = IPhysicsWorld3dComponent> extends GgWorld<Point3, Point4, V, P> {
|
|
11
11
|
readonly visualScene: V;
|
|
12
12
|
readonly physicsWorld: P;
|
|
13
|
-
protected readonly consoleEnabled: boolean;
|
|
14
13
|
readonly loader: Gg3dLoader;
|
|
15
|
-
constructor(visualScene: V, physicsWorld: P
|
|
14
|
+
constructor(visualScene: V, physicsWorld: P);
|
|
16
15
|
addPrimitiveRigidBody(descr: BodyShape3DDescriptor, position?: Point3, rotation?: Point4): Entity3d<V, P>;
|
|
17
16
|
addRenderer<CC extends ICameraComponent<V> = ICameraComponent<V>, RC extends IRenderer3dComponent<V, CC> = IRenderer3dComponent<V, CC>>(camera: CC, canvas?: HTMLCanvasElement, rendererOptions?: Partial<RendererOptions>): Renderer3dEntity<V, CC, RC>;
|
|
18
17
|
}
|
package/dist/3d/gg-3d-world.js
CHANGED
|
@@ -12,14 +12,13 @@ import { Gg3dLoader } from './loader';
|
|
|
12
12
|
import { Entity3d } from './entities/entity-3d';
|
|
13
13
|
import { Renderer3dEntity } from './entities/renderer-3d.entity';
|
|
14
14
|
export class Gg3dWorld extends GgWorld {
|
|
15
|
-
constructor(visualScene, physicsWorld
|
|
16
|
-
super(visualScene, physicsWorld
|
|
15
|
+
constructor(visualScene, physicsWorld) {
|
|
16
|
+
super(visualScene, physicsWorld);
|
|
17
17
|
this.visualScene = visualScene;
|
|
18
18
|
this.physicsWorld = physicsWorld;
|
|
19
|
-
this.consoleEnabled = consoleEnabled;
|
|
20
19
|
this.loader = new Gg3dLoader(this);
|
|
21
|
-
if (
|
|
22
|
-
|
|
20
|
+
if (window.ggstatic) {
|
|
21
|
+
window.ggstatic.registerConsoleCommand(this, 'ph_gravity', (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
23
22
|
if (args.length == 1) {
|
|
24
23
|
args = ['0', '0', '' + -+args[0]]; // mean -Z axis
|
|
25
24
|
}
|
package/dist/3d/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export * from './components/rendering/i-display-object-3d.component';
|
|
|
6
6
|
export * from './components/rendering/i-camera.component';
|
|
7
7
|
export * from './components/rendering/i-renderer-3d.component';
|
|
8
8
|
export * from './components/rendering/i-visual-scene-3d.component';
|
|
9
|
+
export * from './entities/gg-car/gg-car.entity';
|
|
9
10
|
export * from './entities/controllers/animators/camera-3d.animator';
|
|
10
11
|
export * from './entities/controllers/animators/entity-3d-positioning.animator';
|
|
11
12
|
export * from './entities/entity-3d';
|
|
@@ -15,6 +16,7 @@ export * from './entities/trigger-3d.entity';
|
|
|
15
16
|
export * from './entities/renderer-3d.entity';
|
|
16
17
|
export * from './entities/i-renderable-3d.entity';
|
|
17
18
|
export * from './entities/controllers/input/car-keyboard-handling.controller';
|
|
19
|
+
export * from './entities/controllers/input/gg-car-keyboard-handling.controller';
|
|
18
20
|
export * from './entities/controllers/input/free-camera.controller';
|
|
19
21
|
export * from './entities/controllers/input/orbit-camera.controller';
|
|
20
22
|
export * from './interfaces/i-positionable-3d';
|
package/dist/3d/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export * from './components/rendering/i-display-object-3d.component';
|
|
|
6
6
|
export * from './components/rendering/i-camera.component';
|
|
7
7
|
export * from './components/rendering/i-renderer-3d.component';
|
|
8
8
|
export * from './components/rendering/i-visual-scene-3d.component';
|
|
9
|
+
export * from './entities/gg-car/gg-car.entity';
|
|
9
10
|
export * from './entities/controllers/animators/camera-3d.animator';
|
|
10
11
|
export * from './entities/controllers/animators/entity-3d-positioning.animator';
|
|
11
12
|
export * from './entities/entity-3d';
|
|
@@ -15,6 +16,7 @@ export * from './entities/trigger-3d.entity';
|
|
|
15
16
|
export * from './entities/renderer-3d.entity';
|
|
16
17
|
export * from './entities/i-renderable-3d.entity';
|
|
17
18
|
export * from './entities/controllers/input/car-keyboard-handling.controller';
|
|
19
|
+
export * from './entities/controllers/input/gg-car-keyboard-handling.controller';
|
|
18
20
|
export * from './entities/controllers/input/free-camera.controller';
|
|
19
21
|
export * from './entities/controllers/input/orbit-camera.controller';
|
|
20
22
|
export * from './interfaces/i-positionable-3d';
|