minerender 2.1.0-alpha.33 → 2.1.0-alpha.34

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.
@@ -831,6 +831,8 @@ declare class BlockTints {
831
831
 
832
832
  interface Instanceable {
833
833
  nextInstance(): InstanceReference<SceneObject>;
834
+ removeInstanceAt(index: number): void;
835
+ isInstanceActive(index: number, reference: InstanceReference<Instanceable>): boolean;
834
836
  getMatrixAt(index: number, matrix?: Matrix4): Matrix4;
835
837
  setMatrixAt(index: number, matrix: Matrix4): void;
836
838
  setPositionRotationScaleAt(index: number, position?: Vector3, rotation?: Euler, scale?: Vector3): void;
@@ -843,12 +845,15 @@ interface Instanceable {
843
845
  }
844
846
  declare function isInstanceable(obj: any): obj is Instanceable;
845
847
 
846
- declare class InstanceReference<T extends Instanceable> implements Transformable {
848
+ declare class InstanceReference<T extends Instanceable> implements Transformable, Disposable {
847
849
  readonly instanceable: T;
848
850
  readonly index: number;
849
851
  readonly isInstanceReference: true;
850
852
  constructor(instanceable: T, index: number);
851
853
  nextInstance(): InstanceReference<SceneObject>;
854
+ private get activeInstanceable();
855
+ removeFromScene(): void;
856
+ dispose(): void;
852
857
  getMatrix(matrix?: Matrix4): Matrix4;
853
858
  setMatrix(matrix: Matrix4): void;
854
859
  setPositionRotationScale(position?: Vector3, rotation?: Euler, scale?: Vector3): void;
@@ -878,7 +883,6 @@ declare class ModelObject extends SceneObject {
878
883
  private meshesCreated;
879
884
  constructor(originalModel: Model, options?: Partial<ModelObjectOptions>);
880
885
  init(): Promise<void>;
881
- dispose(): void;
882
886
  get textureAtlas(): Maybe<TextureAtlas>;
883
887
  protected loadTextures(): Promise<void>;
884
888
  protected createMeshes(force?: boolean): void;
@@ -1012,6 +1016,9 @@ declare class SceneObject extends Object3D<Object3DEventMap & {
1012
1016
  private materialCallbacks;
1013
1017
  protected _isInstanced: boolean;
1014
1018
  _instanceCounter: number;
1019
+ protected instanceMesh?: InstancedMesh;
1020
+ private readonly instanceReferences;
1021
+ private readonly freeInstanceIndices;
1015
1022
  constructor(options?: Partial<SceneObjectOptions>);
1016
1023
  set scene(scene: MineRenderScene);
1017
1024
  get scene(): MineRenderScene;
@@ -1051,6 +1058,10 @@ declare class SceneObject extends Object3D<Object3DEventMap & {
1051
1058
  get instanceCounter(): number;
1052
1059
  protected constructInstanceReference(i: number): InstanceReference<SceneObject>;
1053
1060
  nextInstance(): InstanceReference<SceneObject>;
1061
+ isInstanceActive(index: number, reference: InstanceReference<Instanceable>): boolean;
1062
+ removeInstanceAt(index: number): void;
1063
+ private growInstances;
1064
+ protected activeInstanceIndices(): Iterable<number>;
1054
1065
  getMatrixAt(index: number, matrix?: Matrix4): Matrix4;
1055
1066
  setMatrixAt(index: number, matrix: Matrix4): void;
1056
1067
  setPositionRotationScaleAt(index: number, position?: Vector3, rotation?: Euler, scale?: Vector3): void;
@@ -1091,6 +1102,7 @@ declare class BlockObject extends SceneObject {
1091
1102
  init(): Promise<void>;
1092
1103
  dispose(): void;
1093
1104
  removeFromScene(): void;
1105
+ private clearModels;
1094
1106
  get state(): {
1095
1107
  [key: string]: string;
1096
1108
  };
@@ -831,6 +831,8 @@ declare class BlockTints {
831
831
 
832
832
  interface Instanceable {
833
833
  nextInstance(): InstanceReference<SceneObject>;
834
+ removeInstanceAt(index: number): void;
835
+ isInstanceActive(index: number, reference: InstanceReference<Instanceable>): boolean;
834
836
  getMatrixAt(index: number, matrix?: Matrix4): Matrix4;
835
837
  setMatrixAt(index: number, matrix: Matrix4): void;
836
838
  setPositionRotationScaleAt(index: number, position?: Vector3, rotation?: Euler, scale?: Vector3): void;
@@ -843,12 +845,15 @@ interface Instanceable {
843
845
  }
844
846
  declare function isInstanceable(obj: any): obj is Instanceable;
845
847
 
846
- declare class InstanceReference<T extends Instanceable> implements Transformable {
848
+ declare class InstanceReference<T extends Instanceable> implements Transformable, Disposable {
847
849
  readonly instanceable: T;
848
850
  readonly index: number;
849
851
  readonly isInstanceReference: true;
850
852
  constructor(instanceable: T, index: number);
851
853
  nextInstance(): InstanceReference<SceneObject>;
854
+ private get activeInstanceable();
855
+ removeFromScene(): void;
856
+ dispose(): void;
852
857
  getMatrix(matrix?: Matrix4): Matrix4;
853
858
  setMatrix(matrix: Matrix4): void;
854
859
  setPositionRotationScale(position?: Vector3, rotation?: Euler, scale?: Vector3): void;
@@ -878,7 +883,6 @@ declare class ModelObject extends SceneObject {
878
883
  private meshesCreated;
879
884
  constructor(originalModel: Model, options?: Partial<ModelObjectOptions>);
880
885
  init(): Promise<void>;
881
- dispose(): void;
882
886
  get textureAtlas(): Maybe<TextureAtlas>;
883
887
  protected loadTextures(): Promise<void>;
884
888
  protected createMeshes(force?: boolean): void;
@@ -1012,6 +1016,9 @@ declare class SceneObject extends Object3D<Object3DEventMap & {
1012
1016
  private materialCallbacks;
1013
1017
  protected _isInstanced: boolean;
1014
1018
  _instanceCounter: number;
1019
+ protected instanceMesh?: InstancedMesh;
1020
+ private readonly instanceReferences;
1021
+ private readonly freeInstanceIndices;
1015
1022
  constructor(options?: Partial<SceneObjectOptions>);
1016
1023
  set scene(scene: MineRenderScene);
1017
1024
  get scene(): MineRenderScene;
@@ -1051,6 +1058,10 @@ declare class SceneObject extends Object3D<Object3DEventMap & {
1051
1058
  get instanceCounter(): number;
1052
1059
  protected constructInstanceReference(i: number): InstanceReference<SceneObject>;
1053
1060
  nextInstance(): InstanceReference<SceneObject>;
1061
+ isInstanceActive(index: number, reference: InstanceReference<Instanceable>): boolean;
1062
+ removeInstanceAt(index: number): void;
1063
+ private growInstances;
1064
+ protected activeInstanceIndices(): Iterable<number>;
1054
1065
  getMatrixAt(index: number, matrix?: Matrix4): Matrix4;
1055
1066
  setMatrixAt(index: number, matrix: Matrix4): void;
1056
1067
  setPositionRotationScaleAt(index: number, position?: Vector3, rotation?: Euler, scale?: Vector3): void;
@@ -1091,6 +1102,7 @@ declare class BlockObject extends SceneObject {
1091
1102
  init(): Promise<void>;
1092
1103
  dispose(): void;
1093
1104
  removeFromScene(): void;
1105
+ private clearModels;
1094
1106
  get state(): {
1095
1107
  [key: string]: string;
1096
1108
  };
@@ -3001,32 +3001,42 @@ var InstanceReference = class {
3001
3001
  nextInstance() {
3002
3002
  return this.instanceable.nextInstance();
3003
3003
  }
3004
+ get activeInstanceable() {
3005
+ if (!this.instanceable.isInstanceActive(this.index, this)) throw new MineRenderError("Instance has been removed");
3006
+ return this.instanceable;
3007
+ }
3008
+ removeFromScene() {
3009
+ if (this.instanceable.isInstanceActive(this.index, this)) this.instanceable.removeInstanceAt(this.index);
3010
+ }
3011
+ dispose() {
3012
+ this.removeFromScene();
3013
+ }
3004
3014
  getMatrix(matrix) {
3005
- return this.instanceable.getMatrixAt(this.index, matrix);
3015
+ return this.activeInstanceable.getMatrixAt(this.index, matrix);
3006
3016
  }
3007
3017
  setMatrix(matrix) {
3008
- this.instanceable.setMatrixAt(this.index, matrix);
3018
+ this.activeInstanceable.setMatrixAt(this.index, matrix);
3009
3019
  }
3010
3020
  setPositionRotationScale(position, rotation, scale) {
3011
- this.instanceable.setPositionRotationScaleAt(this.index, position, rotation, scale);
3021
+ this.activeInstanceable.setPositionRotationScaleAt(this.index, position, rotation, scale);
3012
3022
  }
3013
3023
  setPosition(position) {
3014
- this.instanceable.setPositionAt(this.index, position);
3024
+ this.activeInstanceable.setPositionAt(this.index, position);
3015
3025
  }
3016
3026
  getPosition() {
3017
- return this.instanceable.getPositionAt(this.index);
3027
+ return this.activeInstanceable.getPositionAt(this.index);
3018
3028
  }
3019
3029
  setRotation(rotation) {
3020
- this.instanceable.setRotationAt(this.index, rotation);
3030
+ this.activeInstanceable.setRotationAt(this.index, rotation);
3021
3031
  }
3022
3032
  getRotation() {
3023
- return this.instanceable.getRotationAt(this.index);
3033
+ return this.activeInstanceable.getRotationAt(this.index);
3024
3034
  }
3025
3035
  setScale(scale) {
3026
- this.instanceable.setScaleAt(this.index, scale);
3036
+ this.activeInstanceable.setScaleAt(this.index, scale);
3027
3037
  }
3028
3038
  getScale() {
3029
- return this.instanceable.getScaleAt(this.index);
3039
+ return this.activeInstanceable.getScaleAt(this.index);
3030
3040
  }
3031
3041
  //TODO: support for custom methods e.g. setting block variants
3032
3042
  };
@@ -3044,6 +3054,8 @@ var SceneObject = class _SceneObject extends import_three10.Object3D {
3044
3054
  this.materialCallbacks = {};
3045
3055
  this._isInstanced = false;
3046
3056
  this._instanceCounter = 0;
3057
+ this.instanceReferences = /* @__PURE__ */ new Map();
3058
+ this.freeInstanceIndices = [];
3047
3059
  this.options = (0, import_ts_deepmerge3.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
3048
3060
  console.log("SceneObject options", this.options);
3049
3061
  }
@@ -3147,6 +3159,8 @@ var SceneObject = class _SceneObject extends import_three10.Object3D {
3147
3159
  createInstancedMesh(name, geometry, material, count) {
3148
3160
  const mesh = new import_three10.InstancedMesh(geometry, material, count);
3149
3161
  mesh.count = 0;
3162
+ this.instanceMesh = mesh;
3163
+ this._isInstanced = true;
3150
3164
  if (name) {
3151
3165
  mesh.name = `mesh:${name}`;
3152
3166
  }
@@ -3214,40 +3228,70 @@ var SceneObject = class _SceneObject extends import_three10.Object3D {
3214
3228
  return new InstanceReference(this, i);
3215
3229
  }
3216
3230
  nextInstance() {
3217
- if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
3218
- const i = this._instanceCounter++;
3219
- this.setMatrixAt(i, new import_three10.Matrix4());
3220
- const mesh = this.children[0];
3221
- if (mesh && isInstancedMesh(mesh)) {
3222
- mesh.count = Math.min(this._instanceCounter, mesh.instanceMatrix.count);
3223
- }
3224
- console.debug(p6, "nextInstance " + i);
3225
- if (i === this.options.maxInstanceCount) {
3226
- console.warn(p6, "Max instance count reached for " + this);
3227
- }
3228
- if (this.scene) {
3229
- this.scene.stats.instanceCount++;
3231
+ const mesh = this.instanceMesh;
3232
+ if (!mesh) throw new MineRenderError("Object is not instanced");
3233
+ const index = this.freeInstanceIndices.pop() ?? mesh.count;
3234
+ if (index >= mesh.instanceMatrix.count) this.growInstances(index + 1);
3235
+ const reference = this.constructInstanceReference(index);
3236
+ this.instanceReferences.set(index, reference);
3237
+ this._instanceCounter = this.instanceReferences.size;
3238
+ mesh.count = Math.max(mesh.count, index + 1);
3239
+ if (mesh.instanceColor) {
3240
+ mesh.setColorAt(index, new import_three10.Color(16777215));
3241
+ mesh.instanceColor.needsUpdate = true;
3242
+ }
3243
+ if (this._scene) this._scene.stats.instanceCount++;
3244
+ this.setMatrixAt(index, new import_three10.Matrix4());
3245
+ return reference;
3246
+ }
3247
+ isInstanceActive(index, reference) {
3248
+ return this.instanceReferences.get(index) === reference;
3249
+ }
3250
+ removeInstanceAt(index) {
3251
+ if (!this.instanceReferences.has(index)) return;
3252
+ const mesh = this.instanceMesh;
3253
+ this.setMatrixAt(index, new import_three10.Matrix4().makeScale(0, 0, 0));
3254
+ this.instanceReferences.delete(index);
3255
+ this.freeInstanceIndices.push(index);
3256
+ this._instanceCounter = this.instanceReferences.size;
3257
+ while (mesh.count > 0 && !this.instanceReferences.has(mesh.count - 1)) mesh.count--;
3258
+ if (this._scene) this._scene.stats.instanceCount--;
3259
+ }
3260
+ growInstances(required) {
3261
+ const mesh = this.instanceMesh;
3262
+ const capacity = Math.max(required, mesh.instanceMatrix.count * 2);
3263
+ const grow = (attribute, fill) => {
3264
+ const array = new Float32Array(capacity * attribute.itemSize).fill(fill);
3265
+ array.set(attribute.array);
3266
+ return new import_three10.InstancedBufferAttribute(array, attribute.itemSize, attribute.normalized, attribute.meshPerAttribute).setUsage(attribute.usage);
3267
+ };
3268
+ const matrix = grow(mesh.instanceMatrix, 0);
3269
+ const color = mesh.instanceColor ? grow(mesh.instanceColor, 1) : null;
3270
+ mesh.dispose();
3271
+ mesh.instanceMatrix = matrix;
3272
+ mesh.instanceColor = color;
3273
+ }
3274
+ *activeInstanceIndices() {
3275
+ if (this.instanceMesh) {
3276
+ yield* this.instanceReferences.keys();
3277
+ } else {
3278
+ for (let i = 0; i < this.instanceCounter; i++) yield i;
3230
3279
  }
3231
- this.notifyDirty();
3232
- return this.constructInstanceReference(i);
3233
3280
  }
3234
3281
  //</editor-fold>
3235
3282
  //<editor-fold desc="TRANSFORMATION">
3236
3283
  getMatrixAt(index, matrix = new import_three10.Matrix4()) {
3237
- if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
3238
- const child = this.children[0];
3239
- if (child && isInstancedMesh(child)) {
3240
- child.getMatrixAt(index, matrix);
3241
- }
3284
+ if (!this.instanceReferences.has(index)) throw new MineRenderError("Instance is not active");
3285
+ this.instanceMesh.getMatrixAt(index, matrix);
3242
3286
  return matrix;
3243
3287
  }
3244
3288
  setMatrixAt(index, matrix) {
3245
- if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
3246
- const child = this.children[0];
3247
- if (child && isInstancedMesh(child)) {
3248
- child.setMatrixAt(index, matrix);
3249
- child.instanceMatrix.needsUpdate = true;
3250
- }
3289
+ if (!this.instanceReferences.has(index)) throw new MineRenderError("Instance is not active");
3290
+ const mesh = this.instanceMesh;
3291
+ mesh.setMatrixAt(index, matrix);
3292
+ mesh.instanceMatrix.needsUpdate = true;
3293
+ mesh.boundingBox = null;
3294
+ mesh.boundingSphere = null;
3251
3295
  this.notifyDirty();
3252
3296
  }
3253
3297
  setPositionRotationScaleAt(index, position, rotation, scale) {
@@ -3298,7 +3342,7 @@ var SceneObject = class _SceneObject extends import_three10.Object3D {
3298
3342
  }
3299
3343
  setPositionRotationScale(position, rotation, scale) {
3300
3344
  if (this.isInstanced) {
3301
- for (let i = 0; i < this.instanceCounter; i++) {
3345
+ for (const i of this.activeInstanceIndices()) {
3302
3346
  this.setPositionRotationScaleAt(i, position, rotation, scale);
3303
3347
  }
3304
3348
  } else {
@@ -3316,7 +3360,7 @@ var SceneObject = class _SceneObject extends import_three10.Object3D {
3316
3360
  }
3317
3361
  setPosition(position) {
3318
3362
  if (this.isInstanced) {
3319
- for (let i = 0; i < this.instanceCounter; i++) {
3363
+ for (const i of this.activeInstanceIndices()) {
3320
3364
  this.setPositionRotationScaleAt(i, position);
3321
3365
  }
3322
3366
  } else {
@@ -3326,14 +3370,14 @@ var SceneObject = class _SceneObject extends import_three10.Object3D {
3326
3370
  }
3327
3371
  getPosition() {
3328
3372
  if (this.isInstanced) {
3329
- return this.getPositionAt(0);
3373
+ return this.getPositionAt(this.instanceReferences.keys().next().value ?? 0);
3330
3374
  } else {
3331
3375
  return this.position;
3332
3376
  }
3333
3377
  }
3334
3378
  setRotation(rotation) {
3335
3379
  if (this.isInstanced) {
3336
- for (let i = 0; i < this.instanceCounter; i++) {
3380
+ for (const i of this.activeInstanceIndices()) {
3337
3381
  this.setPositionRotationScaleAt(i, void 0, rotation);
3338
3382
  }
3339
3383
  } else {
@@ -3343,14 +3387,14 @@ var SceneObject = class _SceneObject extends import_three10.Object3D {
3343
3387
  }
3344
3388
  getRotation() {
3345
3389
  if (this.isInstanced) {
3346
- return this.getRotationAt(0);
3390
+ return this.getRotationAt(this.instanceReferences.keys().next().value ?? 0);
3347
3391
  } else {
3348
3392
  return this.rotation;
3349
3393
  }
3350
3394
  }
3351
3395
  setScale(scale) {
3352
3396
  if (this.isInstanced) {
3353
- for (let i = 0; i < this.instanceCounter; i++) {
3397
+ for (const i of this.activeInstanceIndices()) {
3354
3398
  this.setPositionRotationScaleAt(i, void 0, void 0, scale);
3355
3399
  }
3356
3400
  } else {
@@ -3360,7 +3404,7 @@ var SceneObject = class _SceneObject extends import_three10.Object3D {
3360
3404
  }
3361
3405
  getScale() {
3362
3406
  if (this.isInstanced) {
3363
- return this.getScaleAt(0);
3407
+ return this.getScaleAt(this.instanceReferences.keys().next().value ?? 0);
3364
3408
  } else {
3365
3409
  return this.scale;
3366
3410
  }
@@ -3384,6 +3428,17 @@ var SceneObject = class _SceneObject extends import_three10.Object3D {
3384
3428
  this.notifyDirty();
3385
3429
  }
3386
3430
  disposeAndRemoveAllChildren() {
3431
+ if (this.instanceMesh) {
3432
+ if (this._scene) this._scene.stats.instanceCount -= this.instanceReferences.size;
3433
+ this.instanceReferences.clear();
3434
+ this.freeInstanceIndices.length = 0;
3435
+ this._instanceCounter = 0;
3436
+ this.instanceMesh.count = 0;
3437
+ this.instanceMesh.dispose();
3438
+ this.instanceMesh.removeFromParent();
3439
+ this.instanceMesh = void 0;
3440
+ this._isInstanced = false;
3441
+ }
3387
3442
  while (this.children.length > 0) {
3388
3443
  let c = this.children[0];
3389
3444
  if (isDisposable(c)) {
@@ -4596,10 +4651,6 @@ var ModelObject = class _ModelObject extends SceneObject {
4596
4651
  this.createMeshes();
4597
4652
  this.applyTextures();
4598
4653
  }
4599
- dispose() {
4600
- super.dispose();
4601
- this.atlas?.dispose();
4602
- }
4603
4654
  get textureAtlas() {
4604
4655
  return this.atlas;
4605
4656
  }
@@ -4768,18 +4819,21 @@ var BlockObject = class _BlockObject extends SceneObject {
4768
4819
  }
4769
4820
  }
4770
4821
  dispose() {
4822
+ this.clearModels();
4771
4823
  super.dispose();
4772
4824
  }
4773
4825
  removeFromScene() {
4774
- for (let model of this._models) {
4775
- if (isModelObject(model)) {
4776
- model.removeFromScene();
4777
- } else if (isInstanceReference(model)) {
4778
- model.setScale(new import_three18.Vector3(0, 0, 0));
4779
- }
4780
- }
4826
+ this.clearModels();
4781
4827
  super.removeFromScene();
4782
4828
  }
4829
+ clearModels() {
4830
+ for (const model of this._models.splice(0)) {
4831
+ model.removeFromScene();
4832
+ if (!isInstanceReference(model)) model.dispose();
4833
+ }
4834
+ this._isInstanced = false;
4835
+ this._instanceCounter = 0;
4836
+ }
4783
4837
  get state() {
4784
4838
  return this._state;
4785
4839
  }
@@ -4828,22 +4882,7 @@ var BlockObject = class _BlockObject extends SceneObject {
4828
4882
  return out;
4829
4883
  }
4830
4884
  async recreateModels() {
4831
- const instanceInfo = [];
4832
- if (this.isInstanced) {
4833
- for (let i = 0; i < this.instanceCounter; i++) {
4834
- instanceInfo[i] = this.getMatrixAt(i);
4835
- }
4836
- }
4837
- for (let model of this._models) {
4838
- if (isInstanceReference(model)) {
4839
- model.setScale(new import_three18.Vector3(0, 0, 0));
4840
- } else {
4841
- model.dispose();
4842
- }
4843
- }
4844
- while (this._models.length > 0) {
4845
- this._models.shift();
4846
- }
4885
+ this.clearModels();
4847
4886
  const variantsToCreate = await this.mapStateToVariant(this.state);
4848
4887
  this._variants = variantsToCreate;
4849
4888
  for (let blockStateVariant of variantsToCreate) {
@@ -4894,6 +4933,7 @@ var BlockObject = class _BlockObject extends SceneObject {
4894
4933
  this._instanceCounter = 1;
4895
4934
  }
4896
4935
  obj.setRotation(rotation);
4936
+ obj.setPosition(this.position);
4897
4937
  return obj;
4898
4938
  }
4899
4939
  async resetState() {