object selection

This commit is contained in:
azykov@mail.ru
2026-06-22 14:22:15 +03:00
parent 0b7cdd9f05
commit 21c48e44ee
10 changed files with 267 additions and 62 deletions
@@ -0,0 +1,28 @@
import { action, makeObservable, observable } from "mobx";
import { nextObjectEditMode, type ObjectEditMode } from "../worldEditorState";
import { ViewItem } from "./base";
import type { ObjectGeometryViewItem } from "./objectGeometry";
export class ObjectSelectionViewItem extends ViewItem {
public readonly geometry: ObjectGeometryViewItem;
public mode: ObjectEditMode;
constructor(geometry: ObjectGeometryViewItem, mode: ObjectEditMode) {
super();
this.geometry = geometry;
this.mode = mode;
makeObservable(
this,
{
geometry: observable.ref,
mode: true,
nextMode: action,
},
);
}
public nextMode(): void {
this.mode = nextObjectEditMode(this.mode);
}
}
@@ -1,14 +1,17 @@
import * as THREE from 'three';
import type { ObjectType, V3, Voxel, VoxelGroup } from "../../types";
import { ViewItem } from "./base";
import { action, makeObservable, observable, reaction, type IReactionDisposer } from 'mobx';
import { action, computed, makeObservable, observable, reaction, type IReactionDisposer } from 'mobx';
import { getObjectVoxelGroups } from '../../utils/graphics/voxelGroup';
import { buildVoxelGroupMesh } from '../../utils/graphics/voxelMesh';
import { state } from '../rootState';
import { buildObjectTrimesh } from '../../utils/graphics/mesh';
import { computeBoundingBox } from '../../utils/runtime';
import type { ObjectGeometryViewItem } from './objectGeometry';
import type { ViewState } from '../viewState';
export class ObjectTypeGeometryViewItem extends ViewItem {
public readonly owner: ViewState;
public readonly objectType: ObjectType;
public voxelGroups: VoxelGroup[] | undefined;
@@ -18,8 +21,9 @@ export class ObjectTypeGeometryViewItem extends ViewItem {
private readonly _disposeVoxelReaction: IReactionDisposer;
constructor(objectType: ObjectType) {
constructor(owner: ViewState, objectType: ObjectType) {
super();
this.owner = owner;
this.objectType = objectType;
makeObservable(this, {
voxelGroups: observable.ref,
@@ -27,6 +31,7 @@ export class ObjectTypeGeometryViewItem extends ViewItem {
boundingBox: observable.ref,
meshes: observable.ref,
updateRuntimeData: action,
instances: computed,
});
this._disposeVoxelReaction = reaction(
() => objectType.voxels.map(v => `${v.position}-${v.typeId}`).join('|'),
@@ -78,4 +83,8 @@ export class ObjectTypeGeometryViewItem extends ViewItem {
this.colliderMesh = buildObjectTrimesh(this.objectType, state.world.data.voxelTypes);
this.boundingBox = computeBoundingBox(this.objectType);
}
public get instances(): ObjectGeometryViewItem[] {
return this.owner.objectGeometries.values.filter((o) => o.objectTypeGeometry === this);
}
}
+1 -1
View File
@@ -25,7 +25,7 @@ export class ViewState {
this.objectTypeGeometries = new MobxReconcilerMap<ObjectType, ObjectTypeGeometryViewItem>({
reaction: () => Object.values(world.data.objectTypes),
keyOf: (ot) => ot.id,
mapItem: (ot) => new ObjectTypeGeometryViewItem(ot),
mapItem: (ot) => new ObjectTypeGeometryViewItem(this, ot),
updateItem: () => true,
disposeItem: (item) => { item.dispose(); },
});