Skip to content

Commit aceaa73

Browse files
committed
Sprites face the camera.
1 parent aa09e68 commit aceaa73

File tree

13 files changed

+131
-90
lines changed

13 files changed

+131
-90
lines changed

build/index.js

Lines changed: 59 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ var INDEX_LOC = "index";
4242
var TRANSFORM_LOC = "transform";
4343
var SLOT_SIZE_LOC = "slotSize_and_number";
4444
var INSTANCE_LOC = "instance";
45-
var SPRITE_FLAGS_LOC = "spriteFlag";
45+
var SPRITE_TYPE_LOC = "spriteType";
4646
var CAM_POS_LOC = "camPos";
4747
var CAM_TILT_LOC = "camTilt";
4848
var CAM_TURN_LOC = "camTurn";
@@ -1396,6 +1396,11 @@ var vertexShader_default = `#version 300 es
13961396
13971397
precision highp float;
13981398
1399+
// CONST
1400+
const mat4 identity = mat4(1.0);
1401+
const float SPRITE = 1.0;
1402+
const float threshold = 0.5;
1403+
13991404
// IN
14001405
// shape
14011406
layout(location = 0) in vec2 position;
@@ -1405,7 +1410,7 @@ layout(location = 1) in mat4 transform;
14051410
layout(location = 5) in vec2 slotSize_and_number;
14061411
// instance
14071412
layout(location = 6) in float instance;
1408-
layout(location = 7) in float spriteFlag;
1413+
layout(location = 7) in float spriteType;
14091414
14101415
// UNIFORM
14111416
uniform float maxTextureSize;
@@ -1433,7 +1438,13 @@ void main() {
14331438
float slotX = mod(slotNumber, maxCols);
14341439
float slotY = mod(floor(slotNumber / maxCols), maxRows);
14351440
1436-
vec4 elemPosition = transform * vec4(position, 0.0, 1.0);
1441+
vec4 basePosition = vec4(position, 0.0, 1.0);
1442+
1443+
float spriteFlag = max(0., 1. - 2. * abs(spriteType - SPRITE));
1444+
mat4 billboardMatrix = inverse(camTilt * camTurn);
1445+
basePosition = (spriteFlag * billboardMatrix + (1. - spriteFlag) * identity) * basePosition;
1446+
1447+
vec4 elemPosition = transform * basePosition;
14371448
// elementPosition => relativePosition
14381449
vec4 relativePosition = camTilt * camTurn * camPos * elemPosition;
14391450
relativePosition.z -= camDist;
@@ -1451,9 +1462,6 @@ void main() {
14511462
float g = fract(instance / (256.0 * 255.0));
14521463
float b = fract(instance / 255.0);
14531464
vInstanceColor = vec3(r, g, b);
1454-
1455-
// DUMMY
1456-
vInstanceColor.x += spriteFlag;
14571465
}
14581466
`;
14591467

@@ -4403,6 +4411,20 @@ var VectorUniform;
44034411
VectorUniform2[VectorUniform2["BG_COLOR"] = 0] = "BG_COLOR";
44044412
})(VectorUniform || (VectorUniform = {}));
44054413

4414+
// src/world/sprite/Sprite.ts
4415+
function copySprite(sprite) {
4416+
return {
4417+
transform: Matrix_default.create().copy(sprite.transform),
4418+
imageId: sprite.imageId,
4419+
spriteType: sprite.spriteType
4420+
};
4421+
}
4422+
var SpriteType;
4423+
(function(SpriteType2) {
4424+
SpriteType2[SpriteType2["DEFAULT"] = 0] = "DEFAULT";
4425+
SpriteType2[SpriteType2["SPRITE"] = 1] = "SPRITE";
4426+
})(SpriteType || (SpriteType = {}));
4427+
44064428
// src/graphics/GraphicsEngine.ts
44074429
var glProxy = function(gl) {
44084430
if (!LOG_GL) {
@@ -4602,9 +4624,9 @@ class GraphicsEngine extends Disposable {
46024624
} else {
46034625
this.attributeBuffers.ensureSize(INSTANCE_LOC, instanceCount);
46044626
}
4605-
if (!this.attributeBuffers.hasBuffer(SPRITE_FLAGS_LOC)) {
4627+
if (!this.attributeBuffers.hasBuffer(SPRITE_TYPE_LOC)) {
46064628
this.attributeBuffers.createBuffer({
4607-
location: SPRITE_FLAGS_LOC,
4629+
location: SPRITE_TYPE_LOC,
46084630
target: GL.ARRAY_BUFFER,
46094631
usage: GL.STATIC_DRAW,
46104632
vertexAttribPointerRows: 1,
@@ -4613,7 +4635,7 @@ class GraphicsEngine extends Disposable {
46134635
instanceCount
46144636
});
46154637
} else {
4616-
this.attributeBuffers.ensureSize(SPRITE_FLAGS_LOC, instanceCount);
4638+
this.attributeBuffers.ensureSize(SPRITE_TYPE_LOC, instanceCount);
46174639
}
46184640
return this.attributeBuffers;
46194641
}
@@ -4682,6 +4704,19 @@ class GraphicsEngine extends Disposable {
46824704
}
46834705
});
46844706
}
4707+
static tempBuffer = new Float32Array(2);
4708+
updateSpriteTypes(spriteIds, sprites) {
4709+
const attributeBuffers = this.attributeBuffers;
4710+
attributeBuffers.bindVertexArray();
4711+
attributeBuffers.bindBuffer(SPRITE_TYPE_LOC);
4712+
spriteIds.forEach((spriteId) => {
4713+
const sprite = sprites.at(spriteId);
4714+
const type = sprite?.spriteType ?? SpriteType.DEFAULT;
4715+
GraphicsEngine.tempBuffer[0] = type;
4716+
this.gl.bufferSubData(GL.ARRAY_BUFFER, 1 * Float32Array.BYTES_PER_ELEMENT * spriteId, GraphicsEngine.tempBuffer);
4717+
});
4718+
spriteIds.clear();
4719+
}
46854720
updateUniformMatrix(type, matrix) {
46864721
this.gl.uniformMatrix4fv(this.matrixUniforms[type], false, matrix);
46874722
}
@@ -4746,10 +4781,9 @@ class Motor {
47464781
};
47474782
const updates = [];
47484783
const loop = (time) => {
4749-
updatePayload.deltaTime = Math.min(time - updatePayload.time, MAX_DELTA_TIME);
4750-
updatePayload.time = time;
47514784
handle = requestAnimationFrame(loop);
4752-
this.time = time;
4785+
updatePayload.deltaTime = Math.min(time - updatePayload.time, MAX_DELTA_TIME);
4786+
this.time = updatePayload.time = time;
47534787
updates.length = 0;
47544788
this.updateSchedule.forEach((schedule, update) => {
47554789
if (time < schedule.triggerTime) {
@@ -4759,6 +4793,7 @@ class Motor {
47594793
if (schedule.period && time < schedule.expirationTime) {
47604794
schedule.triggerTime = Math.max(schedule.triggerTime + schedule.period, time);
47614795
} else {
4796+
console.log(update);
47624797
this.updateSchedule.delete(update);
47634798
}
47644799
});
@@ -6084,22 +6119,14 @@ class SpriteGroup {
60846119
}
60856120
}
60866121

6087-
// src/world/sprite/Sprite.ts
6088-
function copySprite(sprite) {
6089-
return {
6090-
name: sprite.name,
6091-
transform: Matrix_default.create().copy(sprite.transform),
6092-
imageId: sprite.imageId
6093-
};
6094-
}
6095-
60966122
// src/world/sprite/update/SpriteUpdateType.ts
60976123
var SpriteUpdateType;
60986124
(function(SpriteUpdateType2) {
60996125
SpriteUpdateType2[SpriteUpdateType2["NONE"] = 0] = "NONE";
61006126
SpriteUpdateType2[SpriteUpdateType2["TRANSFORM"] = 1] = "TRANSFORM";
61016127
SpriteUpdateType2[SpriteUpdateType2["ANIM"] = 2] = "ANIM";
6102-
SpriteUpdateType2[SpriteUpdateType2["ALL"] = 3] = "ALL";
6128+
SpriteUpdateType2[SpriteUpdateType2["TYPE"] = 4] = "TYPE";
6129+
SpriteUpdateType2[SpriteUpdateType2["ALL"] = 7] = "ALL";
61036130
})(SpriteUpdateType || (SpriteUpdateType = {}));
61046131

61056132
// src/world/sprite/aux/SpriteGrid.ts
@@ -6239,6 +6266,7 @@ class StaticSprites {
62396266
class SpriteUpdater {
62406267
spriteTransformUpdate;
62416268
spriteAnimUpdate;
6269+
spriteTypeUpdate;
62426270
sprites;
62436271
set holder(value) {
62446272
this.sprites = value;
@@ -6247,6 +6275,7 @@ class SpriteUpdater {
62476275
constructor({ engine, motor }) {
62486276
this.spriteTransformUpdate = new UpdateRegistry((ids) => engine.updateSpriteTransforms(ids, this.sprites), motor);
62496277
this.spriteAnimUpdate = new UpdateRegistry((ids) => engine.updateSpriteAnims(ids, this.sprites), motor);
6278+
this.spriteTypeUpdate = new UpdateRegistry((ids) => engine.updateSpriteTypes(ids, this.sprites), motor);
62506279
}
62516280
informUpdate(id, type = SpriteUpdateType.ALL) {
62526281
if (this.sprites && id < this.sprites.length) {
@@ -6256,6 +6285,9 @@ class SpriteUpdater {
62566285
if (type & SpriteUpdateType.ANIM) {
62576286
this.spriteAnimUpdate.informUpdate(id);
62586287
}
6288+
if (type & SpriteUpdateType.TYPE) {
6289+
this.spriteTypeUpdate.informUpdate(id);
6290+
}
62596291
}
62606292
}
62616293
}
@@ -6272,6 +6304,7 @@ var LOGO_SIZE = 512;
62726304
var CELLSIZE = 2;
62736305

62746306
class DemoWorld extends AuxiliaryHolder {
6307+
camera;
62756308
constructor({ engine, motor }) {
62766309
super();
62776310
const spritesAccumulator = new SpritesAccumulator;
@@ -6382,11 +6415,8 @@ class DemoWorld extends AuxiliaryHolder {
63826415
spritesAccumulator.addAuxiliary(new FixedSpriteGrid({ cellSize: CELLSIZE }, [
63836416
{
63846417
imageId: DOBUKI,
6385-
transform: Matrix_default.create().translate(0, 0, -1)
6386-
},
6387-
{
6388-
imageId: DOBUKI,
6389-
transform: Matrix_default.create().translate(0, 0, -1).rotateY(Math.PI)
6418+
spriteType: SpriteType.SPRITE,
6419+
transform: Matrix_default.create().translate(0, 0, 0)
63906420
}
63916421
], [
63926422
...[
@@ -6422,22 +6452,13 @@ class DemoWorld extends AuxiliaryHolder {
64226452
const camera = new Camera({ engine, motor });
64236453
camera.addAuxiliary(new ResizeAux({ engine }));
64246454
this.addAuxiliary(camera);
6455+
this.camera = camera;
64256456
camera.posMatrix.moveBlocker = {
64266457
isBlocked(pos) {
64276458
const [cx, cy, cz] = PositionMatrix.getCellPos(pos, 2);
64286459
return cx === 0 && cy === 0 && cz === -3;
64296460
}
64306461
};
6431-
spritesAccumulator.addAuxiliary(new FixedSpriteGrid({ cellSize: CELLSIZE }, [
6432-
{
6433-
imageId: DOBUKI,
6434-
transform: Matrix_default.create().translate(0, 0, -1)
6435-
},
6436-
{
6437-
imageId: DOBUKI,
6438-
transform: Matrix_default.create().translate(0, 0, -1).rotateY(Math.PI)
6439-
}
6440-
]));
64416462
spritesAccumulator.addAuxiliary(new SpriteGrid({ yRange: [0, 0] }, {
64426463
getSpritesAtCell: (cell) => [
64436464
{
@@ -6504,7 +6525,6 @@ async function testCanvas(canvas) {
65046525
pixelListener.y = y;
65056526
});
65066527
const engine = new GraphicsEngine(canvas);
6507-
engine.setPixelListener(pixelListener);
65086528
const motor = new Motor;
65096529
const core = new AuxiliaryHolder;
65106530
const world = new DemoWorld({ engine, motor });
@@ -6525,4 +6545,4 @@ export {
65256545
hello
65266546
};
65276547

6528-
//# debugId=026FCEB5FA262A6164756e2164756e21
6548+
//# debugId=A2434C825D92470464756e2164756e21

0 commit comments

Comments
 (0)