Skip to content

Commit

Permalink
Merge pull request #40 from MetacityTools/dev
Browse files Browse the repository at this point in the history
Releasing 0.5.2
  • Loading branch information
vojtatom authored Aug 3, 2023
2 parents 9d5afa6 + 7ceeb7f commit 3339a18
Show file tree
Hide file tree
Showing 191 changed files with 3,568 additions and 2,978 deletions.
3 changes: 3 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
"^@editor/(.*)$",
"^@elements/(.*)$",
"^@shared/(.*)$",
"^@data/(.*)$",
"^@context/(.*)$",
"^@hooks/(.*)$",
"^@assets/(.*)$",
"^[./]"
],
Expand Down
28 changes: 19 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,38 @@ Currently:

These features are planned for the future, and scheduled for a specific release.

### v0.5.1 - Work in progress
### v0.5.2 - Work in progress

- [x] Export screenshot action
- [x] Refactored Global context and processing status - https://github.com/MetacityTools/Studio/issues/33
- [x] Projecting models onto models (2D onto 3D) - https://github.com/MetacityTools/geometry.ts
- [x] Replace json style editor with something more user friendly
- [x] Add a way to add custom styles
- [ ] Switching colormaps for scalars
- [x] Editable input for colors
- [ ] Switching shaders for individual models
- [ ] Randomize colors - default colormap
- [x] Feedback - show notifications on the bottom of the screen
- [x] Tables - add notification on data assignment
- [ ] Loading points and lines from SHP
- [ ] Lock camera position (two buttons - pan and rotation) + locking height during panning as in map

### v0.5.1 - ✅ Released

GLTF loader now assumes Y+ as up axis (as in Blender) and converts the models to Z+ up axis. This is not a breaking change, but it is necessary to make the models compatible with the rest of the world.

- [x] Dark mode
- [x] Update import menu to allow importing multiple files at once, only separate models, tables, or reference planes
- [x] FIX: glTF glitch composing transforms with parents insice scene graph
- [x] FIX: coloring models when style changes - display live changes on save
- [ ] Color in table view according to metadata amount
- [x] Color in table view according to metadata amount
- [x] Colorize model
- [ ] Adjustable limit of metadata for coloring.git
- [x] Heatmap legend
- [x] Heatmap legendg
- [x] Updated file extension (replacing .metacity with .mcmodel and .json.metactiy with .mcstyle), still supports the old extensions tho
- [x] Tooltip on hover over model and labels in 3D
- [x] FIX: Firefox handling mouse events for hover
- [x] Refactor processing status - https://github.com/MetacityTools/Studio/issues/33
- [x] Loading models based on param - base for https://github.com/MetacityTools/Studio/issues/22
- [ ] Feedback - show notifications on the bottom of the screen
- [ ] Projecting models onto models (2D onto 3D) - ✨WIP https://github.com/vojtatom/geometry
- [ ] Loading points and lines from SHP
- [ ] Export screenshot action
- [ ] Lock camera position (two buttons - pan and rotation)

### v0.5.0 - ✅ Released

Expand Down
366 changes: 355 additions & 11 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "metacity-studio",
"private": true,
"version": "0.5.1",
"version": "0.5.2",
"type": "module",
"scripts": {
"dev": "vite",
Expand All @@ -12,8 +12,10 @@
"@headlessui/react": "^1.7.14",
"@loaders.gl/core": "^3.3.3",
"@loaders.gl/gltf": "^3.3.3",
"@metacity/geometry": "^1.0.0",
"@monaco-editor/react": "^4.5.1",
"@vojtatom/csvts": "^0.1.0",
"@uiw/color-convert": "^1.3.3",
"@uiw/react-color": "^1.3.3",
"allotment": "^1.18.1",
"clsx": "^1.2.1",
"colormap": "^2.3.2",
Expand All @@ -26,6 +28,7 @@
"react-router-dom": "^6.9.0",
"react18-json-view": "^0.0.8",
"shpts": "^1.0.4",
"tablests": "^1.0.1",
"uuid": "^9.0.0",
"web-ifc": "0.0.39",
"web-ifc-three": "0.0.123"
Expand All @@ -35,6 +38,7 @@
"@types/colormap": "^2.3.1",
"@types/node": "^18.16.14",
"@types/react": "^18.0.28",
"@types/react-color": "^3.0.6",
"@types/react-dom": "^18.0.11",
"@types/three": "^0.150.0",
"@types/uuid": "^9.0.1",
Expand Down
Binary file added studio/src/assets/ikea.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added studio/src/assets/ikea2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added studio/src/assets/ikea3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added studio/src/assets/ikea4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 22 additions & 2 deletions studio/src/assets/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,19 @@ body,
/* add chevron to select */

select {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
margin: 0;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="20" fill="none" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 9l4 4 4-4"/></svg>');
background-repeat: no-repeat;
background-position: right 0.5rem center;
background-size: 1rem 1rem;
padding-right: 1.5rem;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
}

Expand All @@ -89,7 +97,7 @@ body,

@layer components {
.active-border {
@apply border-amber-300 hover:border-amber-400 dark:border-amber-500 hover:dark:border-amber-400;
@apply border-amber-300 hover:border-amber-400 dark:border-amber-700 hover:dark:border-amber-600;
}

.active-text {
Expand All @@ -113,7 +121,7 @@ body,
}

.base-border-hover {
@apply hover:border-amber-400 dark:hover:border-amber-400;
@apply hover:border-amber-400 dark:hover:border-amber-600;
}

.base-text {
Expand Down Expand Up @@ -183,4 +191,16 @@ body,
.table-td-action-color {
@apply bg-neutral-100 text-neutral-400 dark:bg-neutral-800 dark:text-neutral-400;
}

.button-list-readonly {
@apply bg-neutral-200 dark:bg-neutral-700;
}

.button-list {
@apply button-list-readonly hover:bg-neutral-300 dark:hover:bg-neutral-600;
}

.button-list-no-highlite {
@apply hover:bg-neutral-100 dark:hover:bg-neutral-700;
}
}
1 change: 0 additions & 1 deletion studio/src/bananagl/camera/camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,6 @@ export class Camera {

//Calculate the displacement and adjust the camera's position
const displacement = vec3.sub(this.displacement, newTarPos, tarPos);
console.log(displacement);
vec3.sub(this.position, this.position, displacement);
vec3.sub(this.target, this.target, displacement);
this.updateProjectionViewMatrix();
Expand Down
9 changes: 9 additions & 0 deletions studio/src/bananagl/models/attribute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ export class Attribute {
public type?: number;
private swapArr: TypedArray;

/**
*
* @param name Name of the attribute
* @param buffer Buffer containing the data
* @param size Size of the attribute (1, 2, 3 or 4)
* @param normalized Whether the data should be normalized
* @param stride Stride between each attribute
* @param offset Offset of the first attribute
*/
constructor(
public name: string,
public buffer: Buffer,
Expand Down
2 changes: 2 additions & 0 deletions studio/src/bananagl/models/attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export class Attributes {
else attribute.bind(gl, location);
}

gl.finish();
this.vao = vao;
}

Expand All @@ -46,6 +47,7 @@ export class Attributes {
this.vao = undefined;
this.setup(gl, shader, true);
this.needsRebind_ = false;
gl.finish();
}

get count() {
Expand Down
7 changes: 7 additions & 0 deletions studio/src/bananagl/models/renderable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,11 @@ export abstract class Renderable {
}

abstract get shader(): Shader;

resetTransform() {
this.rotation_ = [0, 0, 0];
this.position_ = [0, 0, 0];
this.scale_ = [1, 1, 1];
this.updateMatrix();
}
}
4 changes: 3 additions & 1 deletion studio/src/bananagl/picking/bvh.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { vec3 } from 'gl-matrix';
import { mat4, vec2, vec3 } from 'gl-matrix';

import { BBox } from './bbox';
import { Ray } from './ray';
Expand All @@ -8,6 +8,8 @@ export interface BVH {
trace(ray: Ray): { t: number; index: number };
pointsInDistance(point: vec3, dist: number): number[];
traceRect(rect: RectSelector): number[];
traceArea(from: vec2, to: vec2): number[];
rebuild(): Promise<void>;
}

export interface BVHNode {
Expand Down
23 changes: 19 additions & 4 deletions studio/src/bananagl/picking/triangles/bvh.triangle.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { vec2, vec3 } from 'gl-matrix';
import { mat4, vec2, vec3 } from 'gl-matrix';

import { Attribute } from '@bananagl/models/attribute';
import { Renderable } from '@bananagl/models/renderable';
Expand Down Expand Up @@ -37,6 +37,11 @@ export class TriangleBVH implements BVH {
this.root = data;
}

async rebuild() {
this.root = undefined;
await this.build();
}

//--------------------------------------------------------------------------------

trace(ray: Ray) {
Expand Down Expand Up @@ -187,17 +192,27 @@ export class TriangleBVH implements BVH {
if (node.right) stack.push(node.right);

if (node.from !== undefined) {
this.traverseLeafTriangleArea(node, indices);
this.traverseLeafTriangleArea(node, from, to, indices);
}
}
}

return indices;
}

private traverseLeafTriangleArea(node: BVHNode, indices: number[]) {
private traverseLeafTriangleArea(node: BVHNode, from: vec2, to: vec2, indices: number[]) {
const data = this.position.buffer.data;
let minx: number, miny: number;
let maxx: number, maxy: number;
let index;
for (let i = node.from!; i < node.to!; i++) {
//TODO optimize, not all triangles are inside the area
//indices.push(i);
index = i * 9;
minx = Math.min(data[index], data[index + 3], data[index + 6]);
miny = Math.min(data[index + 1], data[index + 4], data[index + 7]);
maxx = Math.max(data[index], data[index + 3], data[index + 6]);
maxy = Math.max(data[index + 1], data[index + 4], data[index + 7]);
if (minx > to[0] || miny > to[1] || maxx < from[0] || maxy < from[1]) continue;
indices.push(i);
}
}
Expand Down
10 changes: 9 additions & 1 deletion studio/src/bananagl/renderer/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export class Renderer {

init(canvas: HTMLCanvasElement, options?: WebGLContextAttributes) {
if (this.context || this.window_) return;
console.log('Renderer initialized');

//init with highest performance settings
const gl = canvas.getContext('webgl2', {
Expand Down Expand Up @@ -89,6 +88,9 @@ export class Renderer {
this.running = true;
this.render();

this.afterRenderCallbacks.forEach((callback) => callback());
this.afterRenderCallbacks = [];

const now = performance.now();
const frameTime = now - this.lastFrameTime;
this.lastFrameTime = now;
Expand All @@ -97,4 +99,10 @@ export class Renderer {

requestAnimationFrame(() => this.animationLoop());
}

private afterRenderCallbacks: (() => void)[] = [];

set afterRenderOnce(callback: () => void) {
this.afterRenderCallbacks.push(callback);
}
}
18 changes: 2 additions & 16 deletions studio/src/bananagl/scene/scene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,21 @@ export class Scene {
readonly objects: Renderable[] = [];
readonly toDispose: Renderable[] = [];
readonly picker = new Picker(this);
private onChangeCalls: (() => void)[] = [];

private opaqueObjects_: Renderable[] = [];
private transparentObjects_: Renderable[] = [];
private noDepthObjects_: Renderable[] = [];
private dirtyShaderOrder_ = false;

add(object: Renderable, noSideEffects = false) {
add(object: Renderable) {
this.objects.push(object);
if (!noSideEffects) this.onChangeCalls.forEach((callback) => callback());
this.dirtyShaderOrder_ = true;
}

remove(object: Renderable, noSideEffects = false) {
remove(object: Renderable) {
const idx = this.objects.indexOf(object);
if (idx === -1) return;
this.toDispose.push(...this.objects.splice(idx, 1));

if (!noSideEffects) this.onChangeCalls.forEach((callback) => callback());
this.dirtyShaderOrder_ = true;
}

Expand Down Expand Up @@ -64,16 +60,6 @@ export class Scene {
this.dirtyShaderOrder_ = false;
}

addChangeListener(callback: () => void) {
this.onChangeCalls.push(callback);
}

removeChangeListener(callback: () => void) {
const idx = this.onChangeCalls.indexOf(callback);
if (idx === -1) return;
this.onChangeCalls.splice(idx, 1);
}

get dirtyShaderOrder() {
return this.dirtyShaderOrder_;
}
Expand Down
1 change: 0 additions & 1 deletion studio/src/bananagl/shaders/clone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ function isArray(a: any): a is any[] {
}

export function cloneValue(value: UniformValue) {
//TODO optimize this to prevent reallocation
if (isArray(value)) return value.slice();
if (value instanceof Float32Array) return new Float32Array(value);
if (value instanceof Int32Array) return new Int32Array(value);
Expand Down
1 change: 0 additions & 1 deletion studio/src/bananagl/shaders/shader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ export class Shader {
if (equal(value, uniform.value)) continue;

const loc = uniform.loc;
console.log(` Setting uniforms.${name}`);
this.setValue(value, gl, loc);
uniform.value = cloneValue(value);
}
Expand Down
1 change: 0 additions & 1 deletion studio/src/bananagl/window/controls/mouse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ export class MouseControls {
if (duration < 200) {
hit = trace(this.view, x, y);
} else if (this.keyMap?.shift && this.range) {
console.log('there was a range select', this.range);
hit = traceRange(this.view, this.range.from, this.range.to);
}
}
Expand Down
4 changes: 2 additions & 2 deletions studio/src/bananagl/window/controls/selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class RangeSelection {
}

updateSelection(view: View, x: number, y: number) {
if (!this.inScene) view.scene.add(this.selectionRectangle, true), (this.inScene = true);
if (!this.inScene) view.scene.add(this.selectionRectangle), (this.inScene = true);
this.selectionRectangle.uniforms = {
u_from: view.toNDC(this.x, this.y),
u_to: view.toNDC(x, y),
Expand All @@ -55,7 +55,7 @@ export class RangeSelection {
}

dispose(view: View) {
view.scene.remove(this.selectionRectangle, true);
view.scene.remove(this.selectionRectangle);
}

get from() {
Expand Down
5 changes: 1 addition & 4 deletions studio/src/bananagl/window/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,10 @@ export class View {
y: number = 0;
private width_: number = 0;
private height_: number = 0;
private randomColor: vec3;
readonly camera: Camera = new Camera();
readonly cameraLock = new CameraLock(this.camera);

constructor(readonly scene: Scene) {
this.randomColor = [Math.random(), Math.random(), Math.random()];
}
constructor(readonly scene: Scene) {}

resize(x: number, y: number, width: number, height: number) {
this.x = x;
Expand Down
Loading

0 comments on commit 3339a18

Please sign in to comment.