dacha 0.18.0-alpha.9 → 0.18.1
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/contrib/components/bitmap-text/index.d.ts +11 -11
- package/build/contrib/components/bitmap-text/index.js +13 -10
- package/build/contrib/components/index.d.ts +1 -0
- package/build/contrib/components/index.js +1 -0
- package/build/contrib/components/interpolation/index.d.ts +85 -0
- package/build/contrib/components/interpolation/index.js +101 -0
- package/build/contrib/components/mesh/index.d.ts +13 -13
- package/build/contrib/components/mesh/index.js +12 -9
- package/build/contrib/components/pixi-view/index.d.ts +5 -5
- package/build/contrib/components/pixi-view/index.js +5 -2
- package/build/contrib/components/rigid-body/index.d.ts +8 -0
- package/build/contrib/components/rigid-body/index.js +8 -0
- package/build/contrib/components/shape/index.d.ts +20 -36
- package/build/contrib/components/shape/index.js +27 -23
- package/build/contrib/components/sprite/index.d.ts +22 -14
- package/build/contrib/components/sprite/index.js +23 -10
- package/build/contrib/systems/index.d.ts +2 -0
- package/build/contrib/systems/index.js +1 -0
- package/build/contrib/systems/interpolator/api.d.ts +40 -0
- package/build/contrib/systems/interpolator/api.js +70 -0
- package/build/contrib/systems/interpolator/index.d.ts +3 -0
- package/build/contrib/systems/interpolator/index.js +2 -0
- package/build/contrib/systems/interpolator/system.d.ts +31 -0
- package/build/contrib/systems/interpolator/system.js +96 -0
- package/build/contrib/systems/interpolator/tests/helpers.d.ts +13 -0
- package/build/contrib/systems/interpolator/tests/helpers.js +45 -0
- package/build/contrib/systems/interpolator/utils.d.ts +5 -0
- package/build/contrib/systems/interpolator/utils.js +41 -0
- package/build/contrib/systems/physics-system/api.d.ts +45 -1
- package/build/contrib/systems/physics-system/api.js +49 -0
- package/build/contrib/systems/physics-system/consts.d.ts +3 -1
- package/build/contrib/systems/physics-system/consts.js +4 -1
- package/build/contrib/systems/physics-system/physics-system.js +7 -1
- package/build/contrib/systems/physics-system/subsystems/collision-detection/dynamic-aabb-tree/index.d.ts +1 -1
- package/build/contrib/systems/physics-system/subsystems/collision-detection/dynamic-aabb-tree/index.js +21 -15
- package/build/contrib/systems/physics-system/subsystems/collision-detection/index.d.ts +11 -11
- package/build/contrib/systems/physics-system/subsystems/collision-detection/index.js +130 -124
- package/build/contrib/systems/physics-system/subsystems/collision-detection/query-utils.d.ts +5 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/query-utils.js +97 -81
- package/build/contrib/systems/physics-system/subsystems/collision-detection/types.d.ts +0 -15
- package/build/contrib/systems/physics-system/subsystems/collision-detection/utils.d.ts +3 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/utils.js +9 -0
- package/build/contrib/systems/physics-system/subsystems/physics/mass-properties.js +1 -1
- package/build/contrib/systems/physics-system/types.d.ts +12 -2
- package/build/contrib/systems/renderer/actor-render-tree.js +15 -6
- package/build/contrib/systems/renderer/builders/mesh-builder/index.d.ts +0 -1
- package/build/contrib/systems/renderer/builders/mesh-builder/index.js +0 -21
- package/build/contrib/systems/renderer/builders/pixi-view-builder/index.js +2 -1
- package/build/contrib/systems/renderer/builders/sprite-builder/index.js +8 -0
- package/build/contrib/systems/renderer/material/consts.d.ts +1 -1
- package/build/contrib/systems/renderer/material/consts.js +3 -1
- package/build/contrib/systems/renderer/material/index.js +11 -5
- package/build/engine/data-lib/index.d.ts +1 -1
- package/build/engine/data-lib/index.js +1 -1
- package/build/engine/data-lib/pool.d.ts +9 -0
- package/build/engine/data-lib/pool.js +19 -0
- package/build/engine/game-loop.js +3 -3
- package/build/engine/math-lib/math/ops.d.ts +16 -0
- package/build/engine/math-lib/math/ops.js +25 -0
- package/package.json +1 -1
- package/build/contrib/systems/physics-system/subsystems/collision-detection/dispersion-calculator/index.d.ts +0 -11
- package/build/contrib/systems/physics-system/subsystems/collision-detection/dispersion-calculator/index.js +0 -41
- package/build/engine/data-lib/sort/index.d.ts +0 -1
- package/build/engine/data-lib/sort/index.js +0 -1
- package/build/engine/data-lib/sort/insertion-sort.d.ts +0 -1
- package/build/engine/data-lib/sort/insertion-sort.js +0 -14
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Vector2 } from '../../../../../engine/math-lib';
|
|
1
2
|
import { Collider, Transform } from '../../../../components';
|
|
2
3
|
import { geometryBuilders } from './geometry-builders';
|
|
3
4
|
import { aabbBuilders } from './aabb-builders';
|
|
@@ -10,7 +11,7 @@ export function buildQueryProxy(type, params) {
|
|
|
10
11
|
aabb: aabbBuilders[type](geometry),
|
|
11
12
|
geometry,
|
|
12
13
|
layer: params.layer,
|
|
13
|
-
excludedActors: params.excludeActors
|
|
14
|
+
excludedActors: params.excludeActors?.length
|
|
14
15
|
? new Set(params.excludeActors)
|
|
15
16
|
: undefined,
|
|
16
17
|
actorFilter: params.actorFilter,
|
|
@@ -62,130 +63,145 @@ export const getActorCastQueryType = (params) => {
|
|
|
62
63
|
return null;
|
|
63
64
|
}
|
|
64
65
|
};
|
|
66
|
+
export const makeCastHit = () => ({
|
|
67
|
+
actor: undefined,
|
|
68
|
+
point: { x: 0, y: 0 },
|
|
69
|
+
normal: new Vector2(0, 0),
|
|
70
|
+
distance: 0,
|
|
71
|
+
});
|
|
72
|
+
const cloneCastHit = (hit) => ({
|
|
73
|
+
actor: hit.actor,
|
|
74
|
+
point: hit.point,
|
|
75
|
+
normal: hit.normal,
|
|
76
|
+
distance: hit.distance,
|
|
77
|
+
});
|
|
78
|
+
export const makeOverlapHit = () => ({
|
|
79
|
+
actor: undefined,
|
|
80
|
+
normal: new Vector2(0, 0),
|
|
81
|
+
penetration: 0,
|
|
82
|
+
contactPoints: [],
|
|
83
|
+
});
|
|
84
|
+
const cloneOverlapHit = (hit) => ({
|
|
85
|
+
actor: hit.actor,
|
|
86
|
+
normal: hit.normal,
|
|
87
|
+
penetration: hit.penetration,
|
|
88
|
+
contactPoints: hit.contactPoints,
|
|
89
|
+
});
|
|
65
90
|
export const overlap = (type, queryProxy, proxies) => {
|
|
91
|
+
const scratch = makeOverlapHit();
|
|
66
92
|
const hits = [];
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (!checker) {
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
const intersection = checker(queryProxy.geometry, proxy.geometry);
|
|
74
|
-
if (!intersection) {
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
const hit = {
|
|
78
|
-
actor: proxy.actor,
|
|
79
|
-
normal: intersection.normal.clone().multiplyNumber(-1),
|
|
80
|
-
penetration: intersection.penetration,
|
|
81
|
-
contactPoints: intersection.contactPoints,
|
|
82
|
-
};
|
|
83
|
-
if (queryProxy.hitFilter && !queryProxy.hitFilter(hit)) {
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
hits.push(hit);
|
|
87
|
-
}
|
|
93
|
+
overlapEach(type, queryProxy, proxies, scratch, (hit) => {
|
|
94
|
+
hits.push(cloneOverlapHit(hit));
|
|
95
|
+
});
|
|
88
96
|
return hits;
|
|
89
97
|
};
|
|
90
98
|
export const raycast = (queryProxy, proxies) => {
|
|
99
|
+
const scratch = makeCastHit();
|
|
91
100
|
let nearestDistance = Infinity;
|
|
92
101
|
let nearestHit = null;
|
|
93
|
-
|
|
94
|
-
const collider = proxy.actor.getComponent(Collider);
|
|
95
|
-
const hit = raycastCheckers.ray[collider.shape.type](queryProxy.geometry, proxy.geometry);
|
|
96
|
-
if (!hit) {
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
const castHit = {
|
|
100
|
-
actor: proxy.actor,
|
|
101
|
-
point: hit.point,
|
|
102
|
-
normal: hit.normal,
|
|
103
|
-
distance: hit.distance,
|
|
104
|
-
};
|
|
105
|
-
if (queryProxy.hitFilter && !queryProxy.hitFilter(castHit)) {
|
|
106
|
-
continue;
|
|
107
|
-
}
|
|
102
|
+
raycastEach(queryProxy, proxies, scratch, (hit) => {
|
|
108
103
|
if (hit.distance < nearestDistance) {
|
|
109
|
-
nearestHit = castHit;
|
|
110
104
|
nearestDistance = hit.distance;
|
|
105
|
+
nearestHit = nearestHit ?? makeCastHit();
|
|
106
|
+
nearestHit.actor = hit.actor;
|
|
107
|
+
nearestHit.point = hit.point;
|
|
108
|
+
nearestHit.normal = hit.normal;
|
|
109
|
+
nearestHit.distance = hit.distance;
|
|
111
110
|
}
|
|
112
|
-
}
|
|
111
|
+
});
|
|
113
112
|
return nearestHit;
|
|
114
113
|
};
|
|
115
114
|
export const raycastAll = (queryProxy, proxies) => {
|
|
115
|
+
const scratch = makeCastHit();
|
|
116
116
|
const hits = [];
|
|
117
|
+
raycastEach(queryProxy, proxies, scratch, (hit) => {
|
|
118
|
+
hits.push(cloneCastHit(hit));
|
|
119
|
+
});
|
|
120
|
+
hits.sort((arg1, arg2) => arg1.distance - arg2.distance);
|
|
121
|
+
return hits;
|
|
122
|
+
};
|
|
123
|
+
export const shapeCast = (type, queryProxy, proxies) => {
|
|
124
|
+
const scratch = makeCastHit();
|
|
125
|
+
let nearestDistance = Infinity;
|
|
126
|
+
let nearestHit = null;
|
|
127
|
+
shapeCastEach(type, queryProxy, proxies, scratch, (hit) => {
|
|
128
|
+
if (hit.distance < nearestDistance) {
|
|
129
|
+
nearestDistance = hit.distance;
|
|
130
|
+
nearestHit = nearestHit ?? makeCastHit();
|
|
131
|
+
nearestHit.actor = hit.actor;
|
|
132
|
+
nearestHit.point = hit.point;
|
|
133
|
+
nearestHit.normal = hit.normal;
|
|
134
|
+
nearestHit.distance = hit.distance;
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
return nearestHit;
|
|
138
|
+
};
|
|
139
|
+
export const shapeCastAll = (type, queryProxy, proxies) => {
|
|
140
|
+
const scratch = makeCastHit();
|
|
141
|
+
const hits = [];
|
|
142
|
+
shapeCastEach(type, queryProxy, proxies, scratch, (hit) => {
|
|
143
|
+
hits.push(cloneCastHit(hit));
|
|
144
|
+
});
|
|
145
|
+
hits.sort((arg1, arg2) => arg1.distance - arg2.distance);
|
|
146
|
+
return hits;
|
|
147
|
+
};
|
|
148
|
+
export const raycastEach = (queryProxy, proxies, hit, callback) => {
|
|
117
149
|
for (const proxy of proxies) {
|
|
118
150
|
const collider = proxy.actor.getComponent(Collider);
|
|
119
|
-
const
|
|
120
|
-
if (!
|
|
151
|
+
const result = raycastCheckers.ray[collider.shape.type](queryProxy.geometry, proxy.geometry);
|
|
152
|
+
if (!result) {
|
|
121
153
|
continue;
|
|
122
154
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
};
|
|
129
|
-
if (queryProxy.hitFilter && !queryProxy.hitFilter(castHit)) {
|
|
155
|
+
hit.actor = proxy.actor;
|
|
156
|
+
hit.point = result.point;
|
|
157
|
+
hit.normal = result.normal;
|
|
158
|
+
hit.distance = result.distance;
|
|
159
|
+
if (queryProxy.hitFilter && !queryProxy.hitFilter(hit)) {
|
|
130
160
|
continue;
|
|
131
161
|
}
|
|
132
|
-
|
|
162
|
+
callback(hit);
|
|
133
163
|
}
|
|
134
|
-
hits.sort((arg1, arg2) => arg1.distance - arg2.distance);
|
|
135
|
-
return hits;
|
|
136
164
|
};
|
|
137
|
-
export const
|
|
138
|
-
let nearestDistance = Infinity;
|
|
139
|
-
let nearestHit = null;
|
|
165
|
+
export const shapeCastEach = (type, queryProxy, proxies, hit, callback) => {
|
|
140
166
|
for (const proxy of proxies) {
|
|
141
167
|
const collider = proxy.actor.getComponent(Collider);
|
|
142
168
|
const checker = shapeCastCheckers[type]?.[collider.shape.type];
|
|
143
169
|
if (!checker) {
|
|
144
170
|
continue;
|
|
145
171
|
}
|
|
146
|
-
const
|
|
147
|
-
if (!
|
|
172
|
+
const result = checker(queryProxy.geometry, proxy.geometry);
|
|
173
|
+
if (!result) {
|
|
148
174
|
continue;
|
|
149
175
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
distance: castHit.distance,
|
|
155
|
-
};
|
|
176
|
+
hit.actor = proxy.actor;
|
|
177
|
+
hit.point = result.point;
|
|
178
|
+
hit.normal = result.normal;
|
|
179
|
+
hit.distance = result.distance;
|
|
156
180
|
if (queryProxy.hitFilter && !queryProxy.hitFilter(hit)) {
|
|
157
181
|
continue;
|
|
158
182
|
}
|
|
159
|
-
|
|
160
|
-
nearestHit = hit;
|
|
161
|
-
nearestDistance = castHit.distance;
|
|
162
|
-
}
|
|
183
|
+
callback(hit);
|
|
163
184
|
}
|
|
164
|
-
return nearestHit;
|
|
165
185
|
};
|
|
166
|
-
export const
|
|
167
|
-
const hits = [];
|
|
186
|
+
export const overlapEach = (type, queryProxy, proxies, hit, callback) => {
|
|
168
187
|
for (const proxy of proxies) {
|
|
169
188
|
const collider = proxy.actor.getComponent(Collider);
|
|
170
|
-
const checker =
|
|
189
|
+
const checker = intersectionCheckers[type]?.[collider.shape.type];
|
|
171
190
|
if (!checker) {
|
|
172
191
|
continue;
|
|
173
192
|
}
|
|
174
|
-
const
|
|
175
|
-
if (!
|
|
193
|
+
const intersection = checker(queryProxy.geometry, proxy.geometry);
|
|
194
|
+
if (!intersection) {
|
|
176
195
|
continue;
|
|
177
196
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
};
|
|
197
|
+
intersection.normal.multiplyNumber(-1);
|
|
198
|
+
hit.actor = proxy.actor;
|
|
199
|
+
hit.normal = intersection.normal;
|
|
200
|
+
hit.penetration = intersection.penetration;
|
|
201
|
+
hit.contactPoints = intersection.contactPoints;
|
|
184
202
|
if (queryProxy.hitFilter && !queryProxy.hitFilter(hit)) {
|
|
185
203
|
continue;
|
|
186
204
|
}
|
|
187
|
-
|
|
205
|
+
callback(hit);
|
|
188
206
|
}
|
|
189
|
-
hits.sort((arg1, arg2) => arg1.distance - arg2.distance);
|
|
190
|
-
return hits;
|
|
191
207
|
};
|
|
@@ -2,7 +2,6 @@ import type { Vector2, Point } from '../../../../../engine/math-lib';
|
|
|
2
2
|
import type { Actor } from '../../../../../engine/actor';
|
|
3
3
|
import type { CastHit, OverlapHit } from '../../types';
|
|
4
4
|
import type { DynamicAABBTreeEntryId } from './dynamic-aabb-tree';
|
|
5
|
-
import type { DispersionCalculator } from './dispersion-calculator';
|
|
6
5
|
export type { Point };
|
|
7
6
|
export interface AABB {
|
|
8
7
|
min: Point;
|
|
@@ -83,7 +82,6 @@ export interface ActorProxy {
|
|
|
83
82
|
aabb: AABB;
|
|
84
83
|
geometry: Geometry;
|
|
85
84
|
orientationData: OrientationData;
|
|
86
|
-
edges: Record<Axis, [SortedItem, SortedItem]>;
|
|
87
85
|
treeEntryId: DynamicAABBTreeEntryId;
|
|
88
86
|
layer: string;
|
|
89
87
|
}
|
|
@@ -96,19 +94,6 @@ export interface QueryProxy {
|
|
|
96
94
|
hitFilter?: (hit: OverlapHit | CastHit) => boolean;
|
|
97
95
|
}
|
|
98
96
|
export type Proxy = ActorProxy | QueryProxy;
|
|
99
|
-
export interface SortedItem {
|
|
100
|
-
proxy: ActorProxy;
|
|
101
|
-
value: number;
|
|
102
|
-
}
|
|
103
|
-
export interface AxisEntry {
|
|
104
|
-
sortedList: SortedItem[];
|
|
105
|
-
dispersionCalculator: DispersionCalculator;
|
|
106
|
-
}
|
|
107
|
-
export type Axis = 'x' | 'y';
|
|
108
|
-
export interface Axes {
|
|
109
|
-
x: AxisEntry;
|
|
110
|
-
y: AxisEntry;
|
|
111
|
-
}
|
|
112
97
|
export type ProxyPair = [ActorProxy, ActorProxy];
|
|
113
98
|
export interface Contact {
|
|
114
99
|
actor1: Actor;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import type { ActorProxy } from './types';
|
|
1
2
|
export declare const isZero: (value: number) => boolean;
|
|
2
3
|
export declare const isDefinitelyPositive: (value: number) => boolean;
|
|
3
4
|
export declare const isDefinitelyNegative: (value: number) => boolean;
|
|
4
5
|
export declare const isGreaterThan: (left: number, right: number) => boolean;
|
|
5
6
|
export declare const isLessThan: (left: number, right: number) => boolean;
|
|
7
|
+
export declare const isStatic: (proxy: ActorProxy) => boolean;
|
|
8
|
+
export declare const isDisabled: (proxy: ActorProxy) => boolean;
|
|
@@ -1,6 +1,15 @@
|
|
|
1
|
+
import { RigidBody, Collider } from '../../../../components';
|
|
1
2
|
import { INTERSECTION_EPSILON } from './constants';
|
|
2
3
|
export const isZero = (value) => Math.abs(value) <= INTERSECTION_EPSILON;
|
|
3
4
|
export const isDefinitelyPositive = (value) => value > INTERSECTION_EPSILON;
|
|
4
5
|
export const isDefinitelyNegative = (value) => value < -INTERSECTION_EPSILON;
|
|
5
6
|
export const isGreaterThan = (left, right) => isDefinitelyPositive(left - right);
|
|
6
7
|
export const isLessThan = (left, right) => isDefinitelyNegative(left - right);
|
|
8
|
+
export const isStatic = (proxy) => {
|
|
9
|
+
const rigidBody = proxy.actor.getComponent(RigidBody);
|
|
10
|
+
return rigidBody?.type === 'static';
|
|
11
|
+
};
|
|
12
|
+
export const isDisabled = (proxy) => {
|
|
13
|
+
const collider = proxy.actor.getComponent(Collider);
|
|
14
|
+
return collider?.disabled === true;
|
|
15
|
+
};
|
|
@@ -2,8 +2,8 @@ import type { SceneSystemOptions } from '../../../engine/system';
|
|
|
2
2
|
import type { Actor } from '../../../engine/actor';
|
|
3
3
|
import type { Vector2, Point } from '../../../engine/math-lib';
|
|
4
4
|
export interface PhysicsSystemOptions extends SceneSystemOptions {
|
|
5
|
-
gravityX
|
|
6
|
-
gravityY
|
|
5
|
+
gravityX?: number;
|
|
6
|
+
gravityY?: number;
|
|
7
7
|
solverIterations?: number;
|
|
8
8
|
linearSleepThreshold?: number;
|
|
9
9
|
angularSleepThreshold?: number;
|
|
@@ -24,6 +24,14 @@ export interface PhysicsQueryFilter<T> {
|
|
|
24
24
|
layer?: string;
|
|
25
25
|
excludeActors?: Actor[];
|
|
26
26
|
actorFilter?: (actor: Actor) => boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Called once per candidate hit to decide whether to keep it.
|
|
29
|
+
*
|
|
30
|
+
* The `hit` object passed to this callback may be reused and is only valid
|
|
31
|
+
* for the duration of the call.
|
|
32
|
+
* Inspect it and return a boolean; do not retain the reference or store it
|
|
33
|
+
* in an external collection.
|
|
34
|
+
*/
|
|
27
35
|
hitFilter?: (hit: T) => boolean;
|
|
28
36
|
}
|
|
29
37
|
export interface CommonCastParams extends PhysicsQueryFilter<CastHit> {
|
|
@@ -45,6 +53,8 @@ export interface OverlapHit {
|
|
|
45
53
|
penetration: number;
|
|
46
54
|
contactPoints: Point[];
|
|
47
55
|
}
|
|
56
|
+
export type CastHitCallback = (hit: CastHit) => void;
|
|
57
|
+
export type OverlapHitCallback = (hit: OverlapHit) => void;
|
|
48
58
|
export interface PointQueryShape {
|
|
49
59
|
type: 'point';
|
|
50
60
|
point: Point;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Container } from 'pixi.js';
|
|
2
2
|
import { Actor } from '../../../engine/actor';
|
|
3
3
|
import { Transform } from '../../components/transform';
|
|
4
|
+
import { Interpolation } from '../../components/interpolation';
|
|
4
5
|
import { Sprite } from '../../components/sprite';
|
|
5
6
|
import { Shape } from '../../components/shape';
|
|
6
7
|
import { PixiView } from '../../components/pixi-view';
|
|
@@ -146,17 +147,25 @@ export class ActorRenderTree {
|
|
|
146
147
|
this.actorParentMap.set(actor, actor.parent);
|
|
147
148
|
}
|
|
148
149
|
updatePosition(container, actor) {
|
|
149
|
-
const { local
|
|
150
|
+
const { local } = actor.getComponent(Transform);
|
|
151
|
+
const interpolation = actor.getComponent(Interpolation);
|
|
152
|
+
const useRender = interpolation !== undefined &&
|
|
153
|
+
!interpolation.disabled &&
|
|
154
|
+
interpolation.initialized;
|
|
155
|
+
const positionX = useRender ? interpolation.renderX : local.position.x;
|
|
156
|
+
const positionY = useRender ? interpolation.renderY : local.position.y;
|
|
157
|
+
const rotation = useRender ? interpolation.renderRotation : local.rotation;
|
|
158
|
+
const { scale } = local;
|
|
150
159
|
const meta = container.__dacha.meta;
|
|
151
160
|
if (rotation !== meta.rotation) {
|
|
152
161
|
container.rotation = rotation;
|
|
153
162
|
meta.rotation = rotation;
|
|
154
163
|
}
|
|
155
|
-
if (!floatEquals(
|
|
156
|
-
!floatEquals(
|
|
157
|
-
container.position.set(
|
|
158
|
-
meta.positionX =
|
|
159
|
-
meta.positionY =
|
|
164
|
+
if (!floatEquals(positionX, meta.positionX) ||
|
|
165
|
+
!floatEquals(positionY, meta.positionY)) {
|
|
166
|
+
container.position.set(positionX, positionY);
|
|
167
|
+
meta.positionX = positionX;
|
|
168
|
+
meta.positionY = positionY;
|
|
160
169
|
}
|
|
161
170
|
if (scale.x !== meta.scaleX || scale.y !== meta.scaleY) {
|
|
162
171
|
container.scale.set(scale.x, scale.y);
|
|
@@ -75,26 +75,6 @@ export class MeshBuilder {
|
|
|
75
75
|
}
|
|
76
76
|
this.materialSystem.updateShader(mesh);
|
|
77
77
|
}
|
|
78
|
-
updateGeometry(mesh) {
|
|
79
|
-
const view = mesh.renderData.view;
|
|
80
|
-
const texture = view.texture;
|
|
81
|
-
const geometry = view.geometry;
|
|
82
|
-
const uvs = texture?.uvs;
|
|
83
|
-
if (!uvs) {
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
const uvAttr = geometry.getAttribute('aUV');
|
|
87
|
-
const uvBuffer = uvAttr.buffer.data;
|
|
88
|
-
uvBuffer[0] = uvs.x0;
|
|
89
|
-
uvBuffer[1] = uvs.y0;
|
|
90
|
-
uvBuffer[2] = uvs.x1;
|
|
91
|
-
uvBuffer[3] = uvs.y1;
|
|
92
|
-
uvBuffer[4] = uvs.x2;
|
|
93
|
-
uvBuffer[5] = uvs.y2;
|
|
94
|
-
uvBuffer[6] = uvs.x3;
|
|
95
|
-
uvBuffer[7] = uvs.y3;
|
|
96
|
-
uvAttr.buffer.update();
|
|
97
|
-
}
|
|
98
78
|
updateTexture(mesh) {
|
|
99
79
|
const view = mesh.renderData.view;
|
|
100
80
|
const meta = view.__dacha.meta;
|
|
@@ -109,6 +89,5 @@ export class MeshBuilder {
|
|
|
109
89
|
const texture = textureArray?.[mesh.currentFrame];
|
|
110
90
|
view.texture = texture ?? Texture.WHITE;
|
|
111
91
|
meta.currentFrame = mesh.currentFrame;
|
|
112
|
-
this.updateGeometry(mesh);
|
|
113
92
|
}
|
|
114
93
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Graphics } from 'pixi.js';
|
|
1
2
|
import { PixiView } from '../../../../components/pixi-view';
|
|
2
3
|
export class PixiViewBuilder {
|
|
3
4
|
destroy(pixiView) {
|
|
@@ -5,7 +6,7 @@ export class PixiViewBuilder {
|
|
|
5
6
|
pixiView.renderData = undefined;
|
|
6
7
|
}
|
|
7
8
|
buildView(pixiView, actor) {
|
|
8
|
-
const view = pixiView.createView();
|
|
9
|
+
const view = pixiView.createView ? pixiView.createView() : new Graphics();
|
|
9
10
|
pixiView.renderData = { view };
|
|
10
11
|
view.__dacha = {
|
|
11
12
|
actor,
|
|
@@ -78,5 +78,13 @@ export class SpriteBuilder {
|
|
|
78
78
|
meta.width = sprite.width;
|
|
79
79
|
meta.height = sprite.height;
|
|
80
80
|
}
|
|
81
|
+
if (sprite.fit === 'repeat') {
|
|
82
|
+
if (sprite.textureOffset.x !== meta.textureOffsetX ||
|
|
83
|
+
sprite.textureOffset.y !== meta.textureOffsetY) {
|
|
84
|
+
view.tilePosition.set(sprite.textureOffset.x, sprite.textureOffset.y);
|
|
85
|
+
meta.textureOffsetX = sprite.textureOffset.x;
|
|
86
|
+
meta.textureOffsetY = sprite.textureOffset.y;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
81
89
|
}
|
|
82
90
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const DEFAULT_VERTEX_SHADER = "\n precision mediump float;\n\n attribute vec2 aPosition;\n attribute vec2 aUV;\n\n uniform mat3 uProjectionMatrix;\n uniform mat3 uWorldTransformMatrix;\n uniform mat3 uTransformMatrix;\n\n varying vec2 vUV;\n\n void main() {\n vUV = aUV;\n\n mat3 mvp = uProjectionMatrix * uWorldTransformMatrix * uTransformMatrix;\n vec3 pos = mvp * vec3(aPosition, 1.0);\n gl_Position = vec4(pos.xy, 0.0, 1.0);\n }\n";
|
|
2
|
-
export declare const DEFAULT_FRAGMENT_SHADER = "\n precision mediump float;\n\n varying vec2 vUV;\n\n uniform sampler2D uSampler;\n uniform vec3 uTint;\n uniform float uAlpha;\n\n void main() {\n vec4 color = texture2D(uSampler, vUV);\n color.rgb *= uTint;\n color *= uAlpha;\n gl_FragColor = color;\n }\n";
|
|
2
|
+
export declare const DEFAULT_FRAGMENT_SHADER = "\n precision mediump float;\n\n varying vec2 vUV;\n\n uniform sampler2D uSampler;\n uniform vec2 uUVOffset;\n uniform vec2 uUVScale;\n uniform vec3 uTint;\n uniform float uAlpha;\n\n void main() {\n vec4 color = texture2D(uSampler, uUVOffset + vUV * uUVScale);\n color.rgb *= uTint;\n color *= uAlpha;\n gl_FragColor = color;\n }\n";
|
|
@@ -24,11 +24,13 @@ export const DEFAULT_FRAGMENT_SHADER = `
|
|
|
24
24
|
varying vec2 vUV;
|
|
25
25
|
|
|
26
26
|
uniform sampler2D uSampler;
|
|
27
|
+
uniform vec2 uUVOffset;
|
|
28
|
+
uniform vec2 uUVScale;
|
|
27
29
|
uniform vec3 uTint;
|
|
28
30
|
uniform float uAlpha;
|
|
29
31
|
|
|
30
32
|
void main() {
|
|
31
|
-
vec4 color = texture2D(uSampler, vUV);
|
|
33
|
+
vec4 color = texture2D(uSampler, uUVOffset + vUV * uUVScale);
|
|
32
34
|
color.rgb *= uTint;
|
|
33
35
|
color *= uAlpha;
|
|
34
36
|
gl_FragColor = color;
|
|
@@ -35,7 +35,9 @@ export class MaterialSystem {
|
|
|
35
35
|
uTime: { value: 0.0, type: 'f32' },
|
|
36
36
|
uTint: { value: [1.0, 1.0, 1.0], type: 'vec3<f32>' },
|
|
37
37
|
uAlpha: { value: 1.0, type: 'f32' },
|
|
38
|
-
|
|
38
|
+
uFrameSize: { value: [0.0, 0.0], type: 'vec2<f32>' },
|
|
39
|
+
uUVOffset: { value: [0.0, 0.0], type: 'vec2<f32>' },
|
|
40
|
+
uUVScale: { value: [1.0, 1.0], type: 'vec2<f32>' },
|
|
39
41
|
...(config && builder?.uniforms?.(config.options)),
|
|
40
42
|
},
|
|
41
43
|
},
|
|
@@ -78,10 +80,14 @@ export class MaterialSystem {
|
|
|
78
80
|
.setValue(tint)
|
|
79
81
|
.toRgbArray([]);
|
|
80
82
|
}
|
|
81
|
-
view.
|
|
82
|
-
view.texture
|
|
83
|
-
|
|
84
|
-
view.
|
|
83
|
+
if (meta.materialTexture !== view.texture) {
|
|
84
|
+
meta.materialTexture = view.texture;
|
|
85
|
+
const { uvs, frame } = view.texture;
|
|
86
|
+
const uniforms = view.shader.resources.uniformsGroup.uniforms;
|
|
87
|
+
uniforms.uUVOffset = [uvs.x0, uvs.y0];
|
|
88
|
+
uniforms.uUVScale = [uvs.x1 - uvs.x0, uvs.y2 - uvs.y0];
|
|
89
|
+
uniforms.uFrameSize = [frame.width, frame.height];
|
|
90
|
+
}
|
|
85
91
|
if (!material || !builder) {
|
|
86
92
|
return;
|
|
87
93
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export class Pool {
|
|
2
|
+
factory;
|
|
3
|
+
reset;
|
|
4
|
+
items = [];
|
|
5
|
+
constructor(factory, reset) {
|
|
6
|
+
this.factory = factory;
|
|
7
|
+
this.reset = reset;
|
|
8
|
+
}
|
|
9
|
+
acquire() {
|
|
10
|
+
return this.items.pop() ?? this.factory();
|
|
11
|
+
}
|
|
12
|
+
release(item) {
|
|
13
|
+
this.reset?.(item);
|
|
14
|
+
this.items.push(item);
|
|
15
|
+
}
|
|
16
|
+
clear() {
|
|
17
|
+
this.items.length = 0;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -27,10 +27,10 @@ export class GameLoop {
|
|
|
27
27
|
this.lag = 0;
|
|
28
28
|
this.bindedTick = this.tick.bind(this);
|
|
29
29
|
}
|
|
30
|
-
tick() {
|
|
30
|
+
tick(timestamp) {
|
|
31
31
|
this.gameLoopId = requestAnimationFrame(this.bindedTick);
|
|
32
|
-
const current =
|
|
33
|
-
const elapsed = Math.min(current - this.previous, this.maxFrameDelta);
|
|
32
|
+
const current = timestamp;
|
|
33
|
+
const elapsed = Math.min(Math.max(current - this.previous, 0), this.maxFrameDelta);
|
|
34
34
|
if (elapsed < this.msPerUpdate) {
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
@@ -118,4 +118,20 @@ export declare class MathOps {
|
|
|
118
118
|
* ```
|
|
119
119
|
*/
|
|
120
120
|
static clamp(value: number, min: number, max: number): number;
|
|
121
|
+
/**
|
|
122
|
+
* Signed shortest angular difference between two angles in radians
|
|
123
|
+
*
|
|
124
|
+
* The result is in (-PI, PI], so `from + delta` is angle-equivalent
|
|
125
|
+
* to `to` while rotating the short way around.
|
|
126
|
+
*
|
|
127
|
+
* @param from - Start angle in radians
|
|
128
|
+
* @param to - End angle in radians
|
|
129
|
+
* @returns Signed delta in radians
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```typescript
|
|
133
|
+
* const delta = MathOps.getAngleDelta(3, -3); // ~0.283, crosses PI
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
static getAngleDelta(from: number, to: number): number;
|
|
121
137
|
}
|
|
@@ -134,4 +134,29 @@ export class MathOps {
|
|
|
134
134
|
}
|
|
135
135
|
return value;
|
|
136
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* Signed shortest angular difference between two angles in radians
|
|
139
|
+
*
|
|
140
|
+
* The result is in (-PI, PI], so `from + delta` is angle-equivalent
|
|
141
|
+
* to `to` while rotating the short way around.
|
|
142
|
+
*
|
|
143
|
+
* @param from - Start angle in radians
|
|
144
|
+
* @param to - End angle in radians
|
|
145
|
+
* @returns Signed delta in radians
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```typescript
|
|
149
|
+
* const delta = MathOps.getAngleDelta(3, -3); // ~0.283, crosses PI
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
static getAngleDelta(from, to) {
|
|
153
|
+
let delta = (to - from) % (2 * Math.PI);
|
|
154
|
+
if (delta > Math.PI) {
|
|
155
|
+
delta -= 2 * Math.PI;
|
|
156
|
+
}
|
|
157
|
+
else if (delta <= -Math.PI) {
|
|
158
|
+
delta += 2 * Math.PI;
|
|
159
|
+
}
|
|
160
|
+
return delta;
|
|
161
|
+
}
|
|
137
162
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { Axis, AABB } from '../types';
|
|
2
|
-
export declare class DispersionCalculator {
|
|
3
|
-
private axis;
|
|
4
|
-
private sampleSize;
|
|
5
|
-
private sum;
|
|
6
|
-
private squaredSum;
|
|
7
|
-
constructor(axis: Axis);
|
|
8
|
-
addToSample(aabb: AABB): void;
|
|
9
|
-
removeFromSample(aabb: AABB): void;
|
|
10
|
-
getDispersion(): number;
|
|
11
|
-
}
|