@woosh/meep-engine 2.84.6 → 2.84.8
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/build/meep.cjs +109 -54
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +109 -54
- package/package.json +1 -1
- package/src/core/collection/array/arrayIndexByEquality.js +1 -0
- package/src/core/collection/list/List.js +25 -17
- package/src/core/collection/list/List.spec.js +73 -0
- package/src/core/process/worker/WorkerBuilder.js +5 -1
- package/src/core/process/worker/WorkerProxy.js +3 -2
- package/src/engine/ecs/Entity.spec.js +33 -0
- package/src/engine/ecs/EntityComponentDataset.js +17 -11
- package/src/engine/graphics/camera/CameraShake.js +1 -127
- package/src/engine/graphics/camera/CameraShakeBehavior.js +91 -0
- package/src/engine/graphics/camera/CameraShakeTraumaBehavior.js +38 -0
- package/src/engine/graphics/ecs/animation/animator/AnimationGraphSystem.js +9 -23
- package/src/engine/graphics/ecs/animation/animator/blending/BlendStateMatrix.js +11 -6
- package/src/engine/graphics/ecs/animation/animator/graph/AnimationGraph.js +20 -12
- package/src/engine/graphics/ecs/animation/animator/graph/AnimationState.js +3 -3
- package/src/engine/graphics/ecs/path/tube/build/estimatePathViaIterativeIntegral.js +1 -1
- package/src/view/View.js +52 -30
- package/src/view/writeCssTransformMatrix.js +26 -0
|
@@ -1,132 +1,6 @@
|
|
|
1
|
-
import Vector3 from "../../../core/geom/Vector3.js";
|
|
2
|
-
|
|
3
1
|
import SimplexNoise from 'simplex-noise';
|
|
2
|
+
import Vector3 from "../../../core/geom/Vector3.js";
|
|
4
3
|
import { seededRandom } from "../../../core/math/random/seededRandom.js";
|
|
5
|
-
import { Behavior } from "../../intelligence/behavior/Behavior.js";
|
|
6
|
-
import { BehaviorStatus } from "../../intelligence/behavior/BehaviorStatus.js";
|
|
7
|
-
import Quaternion from "../../../core/geom/Quaternion.js";
|
|
8
|
-
import { clamp01 } from "../../../core/math/clamp01.js";
|
|
9
|
-
import { makeCubicCurve } from "../../../core/math/spline/makeCubicCurve.js";
|
|
10
|
-
|
|
11
|
-
export class CameraShakeTraumaBehavior extends Behavior {
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
*
|
|
15
|
-
* @param {CameraShakeBehavior} shakeBehavior
|
|
16
|
-
* @param {number} decay amount by which trauma decays per second
|
|
17
|
-
*/
|
|
18
|
-
constructor({
|
|
19
|
-
shakeBehavior,
|
|
20
|
-
decay = 1,
|
|
21
|
-
}) {
|
|
22
|
-
super();
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
this.decay = decay;
|
|
26
|
-
this.trauma = 0;
|
|
27
|
-
|
|
28
|
-
this.shakeBehavior = shakeBehavior;
|
|
29
|
-
|
|
30
|
-
this.formula = makeCubicCurve(0, 0.1, 0.1, 1);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
tick(timeDelta) {
|
|
34
|
-
const shake = this.formula(clamp01(this.trauma));
|
|
35
|
-
|
|
36
|
-
this.trauma = clamp01(this.trauma - timeDelta * this.decay);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
this.shakeBehavior.strength = shake;
|
|
40
|
-
|
|
41
|
-
return BehaviorStatus.Running;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export class CameraShakeBehavior extends Behavior {
|
|
46
|
-
/**
|
|
47
|
-
*
|
|
48
|
-
* @param {number} maxPitch
|
|
49
|
-
* @param {number} maxYaw
|
|
50
|
-
* @param {number} maxRoll
|
|
51
|
-
* @param {number} maxOffsetX
|
|
52
|
-
* @param {number} maxOffsetY
|
|
53
|
-
* @param {number} maxOffsetZ
|
|
54
|
-
* @param {number} strength
|
|
55
|
-
* @param {TopDownCameraController} controller
|
|
56
|
-
*/
|
|
57
|
-
constructor(
|
|
58
|
-
{
|
|
59
|
-
maxPitch = 0,
|
|
60
|
-
maxYaw = 0,
|
|
61
|
-
maxRoll = 0,
|
|
62
|
-
maxOffsetX = 0,
|
|
63
|
-
maxOffsetY = 0,
|
|
64
|
-
maxOffsetZ = 0,
|
|
65
|
-
strength = 0,
|
|
66
|
-
|
|
67
|
-
controller
|
|
68
|
-
}
|
|
69
|
-
) {
|
|
70
|
-
super();
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
*
|
|
74
|
-
* @type {TopDownCameraController}
|
|
75
|
-
*/
|
|
76
|
-
this.controller = controller;
|
|
77
|
-
|
|
78
|
-
this.time = 0;
|
|
79
|
-
|
|
80
|
-
this.timeScale = 1;
|
|
81
|
-
|
|
82
|
-
this.strength = strength;
|
|
83
|
-
|
|
84
|
-
this.shake = new CameraShake();
|
|
85
|
-
|
|
86
|
-
this.shake.limitsRotation.set(maxPitch, maxYaw, maxRoll);
|
|
87
|
-
this.shake.limitsOffset.set(maxOffsetX, maxOffsetY, maxOffsetZ);
|
|
88
|
-
|
|
89
|
-
this.__target = new Vector3();
|
|
90
|
-
this.__rotation = new Vector3();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
initialize() {
|
|
94
|
-
super.initialize();
|
|
95
|
-
|
|
96
|
-
//remember controller transform
|
|
97
|
-
this.__rotation.set(this.controller.pitch, this.controller.yaw, this.controller.roll);
|
|
98
|
-
this.__target.copy(this.controller.target);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
tick(timeDelta) {
|
|
102
|
-
this.time += timeDelta * this.timeScale;
|
|
103
|
-
|
|
104
|
-
const offset = new Vector3();
|
|
105
|
-
const rotation = new Vector3();
|
|
106
|
-
|
|
107
|
-
//read out shake values
|
|
108
|
-
this.shake.read(this.strength, this.time, offset, rotation);
|
|
109
|
-
|
|
110
|
-
const q = new Quaternion();
|
|
111
|
-
|
|
112
|
-
q.fromEulerAngles(this.__rotation.x, this.__rotation.y, this.__rotation.z);
|
|
113
|
-
|
|
114
|
-
offset.applyQuaternion(q);
|
|
115
|
-
|
|
116
|
-
//update controller
|
|
117
|
-
this.controller.target.set(
|
|
118
|
-
this.__target.x + offset.x,
|
|
119
|
-
this.__target.y + offset.y,
|
|
120
|
-
this.__target.z + offset.z,
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
this.controller.pitch = this.__rotation.x + rotation.x;
|
|
124
|
-
this.controller.yaw = this.__rotation.y + rotation.y;
|
|
125
|
-
this.controller.roll = this.__rotation.z + rotation.z;
|
|
126
|
-
|
|
127
|
-
return BehaviorStatus.Running;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
4
|
|
|
131
5
|
/**
|
|
132
6
|
* Based on a 2016 GDC talk by Squirrel Eiserloh "Math for Game Programmers: Juicing Your Cameras With Math"
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import Quaternion from "../../../core/geom/Quaternion.js";
|
|
2
|
+
import Vector3 from "../../../core/geom/Vector3.js";
|
|
3
|
+
import { Behavior } from "../../intelligence/behavior/Behavior.js";
|
|
4
|
+
import { BehaviorStatus } from "../../intelligence/behavior/BehaviorStatus.js";
|
|
5
|
+
import { CameraShake } from "./CameraShake.js";
|
|
6
|
+
|
|
7
|
+
export class CameraShakeBehavior extends Behavior {
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @param {number} maxPitch
|
|
11
|
+
* @param {number} maxYaw
|
|
12
|
+
* @param {number} maxRoll
|
|
13
|
+
* @param {number} maxOffsetX
|
|
14
|
+
* @param {number} maxOffsetY
|
|
15
|
+
* @param {number} maxOffsetZ
|
|
16
|
+
* @param {number} strength
|
|
17
|
+
* @param {TopDownCameraController} controller
|
|
18
|
+
*/
|
|
19
|
+
constructor(
|
|
20
|
+
{
|
|
21
|
+
maxPitch = 0,
|
|
22
|
+
maxYaw = 0,
|
|
23
|
+
maxRoll = 0,
|
|
24
|
+
maxOffsetX = 0,
|
|
25
|
+
maxOffsetY = 0,
|
|
26
|
+
maxOffsetZ = 0,
|
|
27
|
+
strength = 0,
|
|
28
|
+
|
|
29
|
+
controller
|
|
30
|
+
}
|
|
31
|
+
) {
|
|
32
|
+
super();
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
*
|
|
36
|
+
* @type {TopDownCameraController}
|
|
37
|
+
*/
|
|
38
|
+
this.controller = controller;
|
|
39
|
+
|
|
40
|
+
this.time = 0;
|
|
41
|
+
|
|
42
|
+
this.timeScale = 1;
|
|
43
|
+
|
|
44
|
+
this.strength = strength;
|
|
45
|
+
|
|
46
|
+
this.shake = new CameraShake();
|
|
47
|
+
|
|
48
|
+
this.shake.limitsRotation.set(maxPitch, maxYaw, maxRoll);
|
|
49
|
+
this.shake.limitsOffset.set(maxOffsetX, maxOffsetY, maxOffsetZ);
|
|
50
|
+
|
|
51
|
+
this.__target = new Vector3();
|
|
52
|
+
this.__rotation = new Vector3();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
initialize() {
|
|
56
|
+
super.initialize();
|
|
57
|
+
|
|
58
|
+
//remember controller transform
|
|
59
|
+
this.__rotation.set(this.controller.pitch, this.controller.yaw, this.controller.roll);
|
|
60
|
+
this.__target.copy(this.controller.target);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
tick(timeDelta) {
|
|
64
|
+
this.time += timeDelta * this.timeScale;
|
|
65
|
+
|
|
66
|
+
const offset = new Vector3();
|
|
67
|
+
const rotation = new Vector3();
|
|
68
|
+
|
|
69
|
+
//read out shake values
|
|
70
|
+
this.shake.read(this.strength, this.time, offset, rotation);
|
|
71
|
+
|
|
72
|
+
const q = new Quaternion();
|
|
73
|
+
|
|
74
|
+
q.fromEulerAngles(this.__rotation.x, this.__rotation.y, this.__rotation.z);
|
|
75
|
+
|
|
76
|
+
offset.applyQuaternion(q);
|
|
77
|
+
|
|
78
|
+
//update controller
|
|
79
|
+
this.controller.target.set(
|
|
80
|
+
this.__target.x + offset.x,
|
|
81
|
+
this.__target.y + offset.y,
|
|
82
|
+
this.__target.z + offset.z,
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
this.controller.pitch = this.__rotation.x + rotation.x;
|
|
86
|
+
this.controller.yaw = this.__rotation.y + rotation.y;
|
|
87
|
+
this.controller.roll = this.__rotation.z + rotation.z;
|
|
88
|
+
|
|
89
|
+
return BehaviorStatus.Running;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { clamp01 } from "../../../core/math/clamp01.js";
|
|
2
|
+
import { makeCubicCurve } from "../../../core/math/spline/makeCubicCurve.js";
|
|
3
|
+
import { Behavior } from "../../intelligence/behavior/Behavior.js";
|
|
4
|
+
import { BehaviorStatus } from "../../intelligence/behavior/BehaviorStatus.js";
|
|
5
|
+
|
|
6
|
+
export class CameraShakeTraumaBehavior extends Behavior {
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @param {CameraShakeBehavior} shakeBehavior
|
|
11
|
+
* @param {number} decay amount by which trauma decays per second
|
|
12
|
+
*/
|
|
13
|
+
constructor({
|
|
14
|
+
shakeBehavior,
|
|
15
|
+
decay = 1,
|
|
16
|
+
}) {
|
|
17
|
+
super();
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
this.decay = decay;
|
|
21
|
+
this.trauma = 0;
|
|
22
|
+
|
|
23
|
+
this.shakeBehavior = shakeBehavior;
|
|
24
|
+
|
|
25
|
+
this.formula = makeCubicCurve(0, 0.1, 0.1, 1);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
tick(timeDelta) {
|
|
29
|
+
const shake = this.formula(clamp01(this.trauma));
|
|
30
|
+
|
|
31
|
+
this.trauma = clamp01(this.trauma - timeDelta * this.decay);
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
this.shakeBehavior.strength = shake;
|
|
35
|
+
|
|
36
|
+
return BehaviorStatus.Running;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -1,31 +1,17 @@
|
|
|
1
|
+
import { Matrix4 } from "three";
|
|
2
|
+
import { assert } from "../../../../../core/assert.js";
|
|
3
|
+
import Vector4 from "../../../../../core/geom/Vector4.js";
|
|
1
4
|
import { max3 } from "../../../../../core/math/max3.js";
|
|
5
|
+
import { ResourceAccessKind } from "../../../../../core/model/ResourceAccessKind.js";
|
|
6
|
+
import { ResourceAccessSpecification } from "../../../../../core/model/ResourceAccessSpecification.js";
|
|
2
7
|
import { System } from "../../../../ecs/System.js";
|
|
3
|
-
import {
|
|
8
|
+
import { projectSphere } from "../../../util/projectSphere.js";
|
|
9
|
+
import { CameraSystem } from "../../camera/CameraSystem.js";
|
|
4
10
|
import Mesh, { MeshFlags } from "../../mesh/Mesh.js";
|
|
11
|
+
import { MeshEvents } from "../../mesh/MeshEvents.js";
|
|
5
12
|
import { MeshSystem } from "../../mesh/MeshSystem.js";
|
|
6
|
-
import {
|
|
7
|
-
import Vector4 from "../../../../../core/geom/Vector4.js";
|
|
8
|
-
import { Matrix4 } from "three";
|
|
9
|
-
import { CameraSystem } from "../../camera/CameraSystem.js";
|
|
13
|
+
import { AnimationGraph } from "./graph/AnimationGraph.js";
|
|
10
14
|
import { AnimationGraphFlag } from "./graph/AnimationGraphFlag.js";
|
|
11
|
-
import { projectSphere } from "../../../util/projectSphere.js";
|
|
12
|
-
import { MeshEvents } from "../../mesh/MeshEvents.js";
|
|
13
|
-
import { ResourceAccessSpecification } from "../../../../../core/model/ResourceAccessSpecification.js";
|
|
14
|
-
import { ResourceAccessKind } from "../../../../../core/model/ResourceAccessKind.js";
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
*
|
|
18
|
-
* @param {AnimationGraph} graph
|
|
19
|
-
* @param {Mesh} mesh
|
|
20
|
-
* @param {number} entity
|
|
21
|
-
* @param {EntityComponentDataset} ecd
|
|
22
|
-
*/
|
|
23
|
-
function attach(graph, mesh, entity, ecd) {
|
|
24
|
-
graph.attach(mesh);
|
|
25
|
-
|
|
26
|
-
graph.link(entity, ecd);
|
|
27
|
-
|
|
28
|
-
}
|
|
29
15
|
|
|
30
16
|
/**
|
|
31
17
|
* @type {Vector4}
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
import { assert } from "../../../../../../core/assert.js";
|
|
1
2
|
import { lerp } from "../../../../../../core/math/lerp.js";
|
|
2
3
|
|
|
3
4
|
export class BlendStateMatrix {
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {number} size
|
|
8
|
+
*/
|
|
4
9
|
constructor(size) {
|
|
10
|
+
assert.isNonNegativeInteger(size, 'size');
|
|
11
|
+
|
|
5
12
|
this.weights = new Float32Array(size);
|
|
6
13
|
this.timeScales = new Float32Array(size);
|
|
7
14
|
}
|
|
@@ -64,15 +71,13 @@ export class BlendStateMatrix {
|
|
|
64
71
|
*
|
|
65
72
|
* @param {number} v
|
|
66
73
|
*/
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
const tTS = this.timeScales;
|
|
74
|
+
weightsMultiplyScalar(v) {
|
|
75
|
+
const weights = this.weights;
|
|
70
76
|
|
|
71
|
-
const n =
|
|
77
|
+
const n = weights.length;
|
|
72
78
|
|
|
73
79
|
for (let i = 0; i < n; i++) {
|
|
74
|
-
|
|
75
|
-
tTS[i] /= v;
|
|
80
|
+
weights[i] *= v;
|
|
76
81
|
}
|
|
77
82
|
}
|
|
78
83
|
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { AnimationState } from "./AnimationState.js";
|
|
2
|
-
import { AnimationTransition } from "./AnimationTransition.js";
|
|
3
|
-
import { AnimationStateType } from "./AnimationStateType.js";
|
|
4
1
|
import { AnimationMixer } from "three";
|
|
2
|
+
import { assert } from "../../../../../../core/assert.js";
|
|
3
|
+
import { computeHashIntegerArray } from "../../../../../../core/collection/array/computeHashIntegerArray.js";
|
|
4
|
+
import { computeHashFloat } from "../../../../../../core/primitives/numbers/computeHashFloat.js";
|
|
5
|
+
import { threeUpdateTransform } from "../../../../util/threeUpdateTransform.js";
|
|
5
6
|
import { AnimationGraphFlag } from "./AnimationGraphFlag.js";
|
|
6
|
-
import {
|
|
7
|
+
import { AnimationState } from "./AnimationState.js";
|
|
8
|
+
import { AnimationStateType } from "./AnimationStateType.js";
|
|
9
|
+
import { AnimationTransition } from "./AnimationTransition.js";
|
|
7
10
|
import {
|
|
8
11
|
readAnimationGraphDefinitionFromJSON
|
|
9
12
|
} from "./definition/serialization/readAnimationGraphDefinitionFromJSON.js";
|
|
10
|
-
import {
|
|
11
|
-
import { threeUpdateTransform } from "../../../../util/threeUpdateTransform.js";
|
|
12
|
-
import { computeHashIntegerArray } from "../../../../../../core/collection/array/computeHashIntegerArray.js";
|
|
13
|
-
import { computeHashFloat } from "../../../../../../core/primitives/numbers/computeHashFloat.js";
|
|
13
|
+
import { writeAnimationGraphDefinitionToJSON } from "./definition/serialization/writeAnimationGraphDefinitionToJSON.js";
|
|
14
14
|
|
|
15
15
|
export class AnimationGraph {
|
|
16
16
|
constructor() {
|
|
@@ -142,15 +142,22 @@ export class AnimationGraph {
|
|
|
142
142
|
};
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
/**
|
|
146
|
+
*
|
|
147
|
+
* @param {*} def Graph definition JSON
|
|
148
|
+
* @param {number} state
|
|
149
|
+
* @param {number} debtTime
|
|
150
|
+
* @param {number} flags
|
|
151
|
+
*/
|
|
145
152
|
fromJSON({ def, state, debtTime = 0, flags = 0 }) {
|
|
146
|
-
const
|
|
153
|
+
const graph_definition = readAnimationGraphDefinitionFromJSON(def);
|
|
147
154
|
|
|
148
155
|
this.debtTime = debtTime;
|
|
149
156
|
this.flags = flags;
|
|
150
|
-
this.initialize(
|
|
157
|
+
this.initialize(graph_definition);
|
|
151
158
|
|
|
152
159
|
if (state === undefined) {
|
|
153
|
-
state =
|
|
160
|
+
state = graph_definition.states.indexOf(graph_definition.startingSate);
|
|
154
161
|
}
|
|
155
162
|
|
|
156
163
|
this.state = this.states[state];
|
|
@@ -522,7 +529,7 @@ export class AnimationGraph {
|
|
|
522
529
|
}
|
|
523
530
|
|
|
524
531
|
// normalize
|
|
525
|
-
currentBlendState.
|
|
532
|
+
currentBlendState.weightsMultiplyScalar(1 / nAT);
|
|
526
533
|
}
|
|
527
534
|
} else {
|
|
528
535
|
//no active transitions, copy current state's blend matrix
|
|
@@ -553,6 +560,7 @@ export class AnimationGraph {
|
|
|
553
560
|
|
|
554
561
|
if (action === undefined) {
|
|
555
562
|
console.warn(`Action[${i}] is undefined`);
|
|
563
|
+
continue;
|
|
556
564
|
}
|
|
557
565
|
|
|
558
566
|
action.weight = weight;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AnimationStateType } from "./AnimationStateType.js";
|
|
2
1
|
import { BlendStateMatrix } from "../blending/BlendStateMatrix.js";
|
|
2
|
+
import { AnimationStateType } from "./AnimationStateType.js";
|
|
3
3
|
|
|
4
4
|
export class AnimationState {
|
|
5
5
|
constructor() {
|
|
@@ -11,13 +11,13 @@ export class AnimationState {
|
|
|
11
11
|
this.def = null;
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* Incoming transitions
|
|
15
15
|
* @type {AnimationTransition[]}
|
|
16
16
|
*/
|
|
17
17
|
this.inEdges = [];
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* Outgoing transitions
|
|
21
21
|
* @type {AnimationTransition[]}
|
|
22
22
|
*/
|
|
23
23
|
this.outEdges = [];
|
package/src/view/View.js
CHANGED
|
@@ -3,15 +3,18 @@
|
|
|
3
3
|
* @copyright Alex Goldring 2018
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
import AABB2 from "../core/geom/2d/aabb/AABB2.js";
|
|
6
|
+
import { assert } from "../core/assert.js";
|
|
9
7
|
import Signal from "../core/events/signal/Signal.js";
|
|
10
8
|
import { SignalBinding } from "../core/events/signal/SignalBinding.js";
|
|
11
|
-
|
|
12
|
-
import
|
|
9
|
+
|
|
10
|
+
import AABB2 from "../core/geom/2d/aabb/AABB2.js";
|
|
13
11
|
|
|
14
12
|
import { m3_cm_compose_transform } from "../core/geom/mat3/m3_cm_compose_transform.js";
|
|
13
|
+
import Vector1 from "../core/geom/Vector1.js";
|
|
14
|
+
import Vector2 from "../core/geom/Vector2.js";
|
|
15
|
+
import { epsilonEquals } from "../core/math/epsilonEquals.js";
|
|
16
|
+
import { FLT_EPSILON_32 } from "../core/math/FLT_EPSILON_32.js";
|
|
17
|
+
import { writeCssTransformMatrix } from "./writeCssTransformMatrix.js";
|
|
15
18
|
|
|
16
19
|
|
|
17
20
|
const scratch_m3_0 = new Float32Array(9);
|
|
@@ -29,26 +32,7 @@ function setElementTransform(domElement, position, scale, rotation) {
|
|
|
29
32
|
|
|
30
33
|
m3_cm_compose_transform(m3, position.x, position.y, scale.x, scale.y, 0, 0, rotation);
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
/*
|
|
34
|
-
* CSS matrix is:
|
|
35
|
-
* a c e
|
|
36
|
-
* b d f
|
|
37
|
-
* 0 0 1
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
const a = m3[0];
|
|
41
|
-
const b = m3[3];
|
|
42
|
-
const c = m3[1];
|
|
43
|
-
const d = m3[4];
|
|
44
|
-
const e = m3[2];
|
|
45
|
-
const f = m3[5];
|
|
46
|
-
|
|
47
|
-
const transform = "matrix(" + a + ',' + b + ',' + c + ',' + d + ',' + e + ',' + f + ")";
|
|
48
|
-
|
|
49
|
-
const style = domElement.style;
|
|
50
|
-
|
|
51
|
-
style.transform = transform;
|
|
35
|
+
writeCssTransformMatrix(m3, domElement);
|
|
52
36
|
}
|
|
53
37
|
|
|
54
38
|
/**
|
|
@@ -88,6 +72,9 @@ const INITIAL_FLAGS = ViewFlags.Visible;
|
|
|
88
72
|
* @class
|
|
89
73
|
*/
|
|
90
74
|
class View {
|
|
75
|
+
#transform_written = new Float32Array(9);
|
|
76
|
+
#transform_current = new Float32Array(9);
|
|
77
|
+
|
|
91
78
|
/**
|
|
92
79
|
* @constructor
|
|
93
80
|
*/
|
|
@@ -112,31 +99,32 @@ class View {
|
|
|
112
99
|
this.flags = INITIAL_FLAGS;
|
|
113
100
|
|
|
114
101
|
/**
|
|
115
|
-
*
|
|
102
|
+
* @readonly
|
|
116
103
|
* @type {Vector2}
|
|
117
104
|
*/
|
|
118
105
|
const position = this.position = new Vector2(0, 0);
|
|
119
106
|
|
|
120
107
|
/**
|
|
121
|
-
*
|
|
108
|
+
* @readonly
|
|
122
109
|
* @type {Vector1}
|
|
123
110
|
*/
|
|
124
111
|
const rotation = this.rotation = new Vector1(0);
|
|
125
112
|
|
|
126
113
|
/**
|
|
127
|
-
*
|
|
114
|
+
* @readonly
|
|
128
115
|
* @type {Vector2}
|
|
129
116
|
*/
|
|
130
117
|
const scale = this.scale = new Vector2(1, 1);
|
|
131
118
|
|
|
132
119
|
/**
|
|
133
|
-
*
|
|
120
|
+
* @readonly
|
|
134
121
|
* @type {Vector2}
|
|
135
122
|
*/
|
|
136
123
|
const size = this.size = new Vector2(0, 0);
|
|
137
124
|
|
|
138
125
|
/**
|
|
139
126
|
* Origin from which rotation and scaling is applied
|
|
127
|
+
* @readonly
|
|
140
128
|
* @type {Vector2}
|
|
141
129
|
*/
|
|
142
130
|
this.transformOrigin = new Vector2(0.5, 0.5);
|
|
@@ -274,7 +262,41 @@ class View {
|
|
|
274
262
|
* @private
|
|
275
263
|
*/
|
|
276
264
|
__updateTransform() {
|
|
277
|
-
|
|
265
|
+
const position = this.position;
|
|
266
|
+
const scale = this.scale;
|
|
267
|
+
const rotation = this.rotation.getValue();
|
|
268
|
+
|
|
269
|
+
m3_cm_compose_transform(this.#transform_current, position.x, position.y, scale.x, scale.y, 0, 0, rotation);
|
|
270
|
+
|
|
271
|
+
this.#tryWriteTransform();
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
#tryWriteTransform() {
|
|
275
|
+
|
|
276
|
+
const current = this.#transform_current;
|
|
277
|
+
const written = this.#transform_written;
|
|
278
|
+
|
|
279
|
+
for (let i = 0; i < 9; i++) {
|
|
280
|
+
const a = current[i];
|
|
281
|
+
const b = written[i];
|
|
282
|
+
|
|
283
|
+
if (epsilonEquals(a, b, FLT_EPSILON_32)) {
|
|
284
|
+
// common path
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
this.#writeTransform();
|
|
289
|
+
return true;
|
|
290
|
+
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
#writeTransform() {
|
|
297
|
+
writeCssTransformMatrix(this.#transform_current, this.el);
|
|
298
|
+
|
|
299
|
+
this.#transform_written.set(this.#transform_current);
|
|
278
300
|
}
|
|
279
301
|
|
|
280
302
|
/**
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {Float32Array} m3
|
|
4
|
+
* @param {HTMLElement} domElement
|
|
5
|
+
*/
|
|
6
|
+
export function writeCssTransformMatrix(m3, domElement) {
|
|
7
|
+
/*
|
|
8
|
+
* CSS matrix is:
|
|
9
|
+
* a c e
|
|
10
|
+
* b d f
|
|
11
|
+
* 0 0 1
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const a = m3[0];
|
|
15
|
+
const b = m3[3];
|
|
16
|
+
const c = m3[1];
|
|
17
|
+
const d = m3[4];
|
|
18
|
+
const e = m3[2];
|
|
19
|
+
const f = m3[5];
|
|
20
|
+
|
|
21
|
+
const transform = "matrix(" + a + ',' + b + ',' + c + ',' + d + ',' + e + ',' + f + ")";
|
|
22
|
+
|
|
23
|
+
const style = domElement.style;
|
|
24
|
+
|
|
25
|
+
style.transform = transform;
|
|
26
|
+
}
|