Skip to content

Commit

Permalink
feat: Add box in top view
Browse files Browse the repository at this point in the history
Add box in top view and show in 3D view
  • Loading branch information
Kerwin-L committed Jun 27, 2022
1 parent d467bf3 commit 5220663
Show file tree
Hide file tree
Showing 11 changed files with 429 additions and 33 deletions.
111 changes: 95 additions & 16 deletions packages/lb-annotation/src/core/pointCloud/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* @Author: Laoluo luozefeng@sensetime.com
* @Date: 2022-06-13 19:05:33
* @LastEditors: Laoluo luozefeng@sensetime.com
* @LastEditTime: 2022-06-16 19:30:06
* @LastEditTime: 2022-06-27 18:13:11
*/
import * as THREE from 'three';
import {
Expand All @@ -20,14 +20,25 @@ import { PCDLoader } from './PCDLoader';

interface IProps {
container: HTMLElement;
noAppend?: boolean; // temporary;
isOrthographicCamera?: boolean;
orthgraphicParams?: {
left: number;
right: number;
top: number;
bottom: number;
near: number;
far: number;
};
}

export class PointCloud {
public renderer: THREE.WebGLRenderer;

public scene: THREE.Scene;

public camera: THREE.PerspectiveCamera;
public camera: THREE.OrthographicCamera | THREE.PerspectiveCamera;
// public camera: THREE.PerspectiveCamera;

public controls: OrbitControls;

Expand All @@ -39,10 +50,27 @@ export class PointCloud {

private front: any;

constructor({ container }: IProps) {
private isOrthographicCamera = false;

constructor({ container, noAppend, isOrthographicCamera, orthgraphicParams }: IProps) {
this.container = container;
this.renderer = new THREE.WebGLRenderer({ antialias: true });
this.camera = new THREE.PerspectiveCamera(30, this.containerWidth / this.containerHeight, 1, 1000);

// TODO
if (isOrthographicCamera && orthgraphicParams) {
this.isOrthographicCamera = true;
this.camera = new THREE.OrthographicCamera(
orthgraphicParams.left,
orthgraphicParams.right,
orthgraphicParams.top,
orthgraphicParams.bottom,
orthgraphicParams.near,
orthgraphicParams.far,
);
} else {
this.camera = new THREE.PerspectiveCamera(30, this.containerWidth / this.containerHeight, 1, 1000);
}
// this.camera = new THREE.OrthographicCamera(-500, 500, 500, -500, 100, -100);
this.initCamera();

this.scene = new THREE.Scene();
Expand All @@ -52,7 +80,10 @@ export class PointCloud {

this.scene.add(this.axesHelper);
this.scene.add(this.camera);
container.appendChild(this.renderer.domElement);
// TODO
if (!noAppend) {
container.appendChild(this.renderer.domElement);
}

this.init();
}
Expand All @@ -62,24 +93,29 @@ export class PointCloud {
}

get containerHeight() {
return this.container.clientWidth;
return this.container.clientHeight;
}

public initCamera() {
// Camera setting must be setted before Control's initial.
const { camera } = this;
camera.position.set(-100, 15, 15);

// TODO
if (this.isOrthographicCamera) {
camera.position.set(-1, 0, 10);
} else {
camera.position.set(-100, 15, 15);
}
camera.up.set(0, 0, 1);
}

public initControls() {
const { controls } = this;
const centerPoint = [15, 15, 15];
const centerPoint = [0, 0, 0];
controls.target = new THREE.Vector3(...centerPoint); // Camera watching?
controls.addEventListener('change', () => {
this.render();
}); // use if there is no animation loop
controls.minDistance = 1;
controls.maxPolarAngle = Math.PI / 2; // Fobid orbit vertically over 90°

controls.update();
Expand Down Expand Up @@ -107,7 +143,6 @@ export class PointCloud {

// Test for Render
this.generateBox(params);
this.updateCamera(params, EPerspectiveView.LFT);
this.controls.update();
}

Expand All @@ -131,6 +166,34 @@ export class PointCloud {
this.render();
}

/**
* Get OrthographicCamera Params to Change
* @param boxParams
* @returns
*/
public getOrthograhicCamera(boxParams: IBoxParams) {
const { center, volume } = boxParams;
const offset = 10;
const left = center.x - volume.width / 2 - offset;
const right = center.x - volume.width / 2 + offset;
const top = center.y + volume.height / 2 + offset;
const bottom = center.y - volume.height / 2 - offset;

const near = 100;
const far = -100;
const zoom = 500 / near;

return {
left,
right,
top,
bottom,
near,
far,
zoom,
};
}

/**
* Update Camera position & target
* @param boxParams
Expand All @@ -141,6 +204,19 @@ export class PointCloud {
const newVector = this.getCameraVector(center, rotation, volume, perspectiveView);
this.camera.position.set(newVector.x, newVector.y, newVector.z);
this.controls.target = new THREE.Vector3(center.x, center.y, center.z);
// const { left, right, top, bottom, near, far, zoom } = this.getOrthograhicCamera(boxParams);

// console.log('ads', { left, right, top, bottom, near, far, zoom });

// // orthograpic camera
// this.camera.left = left;
// this.camera.right = right;
// this.camera.top = top;
// this.camera.bottom = bottom;
// this.camera.near = near;
// this.camera.far = far;
// this.camera.zoom = zoom;
// this.camera.updateProjectionMatrix();
}

public createThreeMatrix4(matrix4: TMatrix4Tuple) {
Expand All @@ -152,7 +228,7 @@ export class PointCloud {
rotationZ: number,
volume: IVolume,
perspectiveView: EPerspectiveView = EPerspectiveView.Front,
DEFAULT_DISTANCE = 10,
DEFAULT_DISTANCE = 30,
) {
let TcMatrix4 = PerspectiveShiftUtils.frontViewMatrix4(DEFAULT_DISTANCE);

Expand Down Expand Up @@ -215,7 +291,7 @@ export class PointCloud {
return ellipse;
}

public loadPCDFile = (src: string) => {
public loadPCDFile = (src: string, cb?: () => void) => {
this.pcdLoader.load(src, (points: any) => {
points.material.size = 0.3;

Expand All @@ -225,6 +301,10 @@ export class PointCloud {
this.scene.add(circle);

this.render();

if (cb) {
cb();
}
});
};

Expand All @@ -243,17 +323,16 @@ export class PointCloud {
const sprite = new THREE.SpriteMaterial({ map: texture, depthWrite: false });
const boxID = new THREE.Sprite(sprite);
boxID.scale.set(5, 5, 5);
console.log(boxID);
boxID.position.set(-boxParams.volume.width / 2, 0, boxParams.volume.depth / 2 + 0.5);
return boxID;
};

public getTextCanvas(text: string) {
var canvas = document.createElement('canvas');
const canvas = document.createElement('canvas');

var ctx = canvas.getContext('2d');
const ctx = canvas.getContext('2d');
if (ctx) {
ctx.font = 50 + 'px " bold';
ctx.font = `50px bold`;
ctx.fillStyle = 'white';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
Expand Down
27 changes: 17 additions & 10 deletions packages/lb-annotation/src/core/toolOperation/basicToolOperation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ interface IBasicToolOperationProps {
showDefaultCursor?: boolean; // 默认会展示为 none

forbidBasicResultRender?: boolean;

isAppend?: boolean;
}

/**
Expand Down Expand Up @@ -159,7 +161,7 @@ class BasicToolOperation extends EventListener {
this.showDefaultCursor = props.showDefaultCursor || false;

this.destroyCanvas();
this.createCanvas(props.size);
this.createCanvas(props.size, props.isAppend);
this.imgNode = props.imgNode;
this.isImgError = !props.imgNode;
this.basicImgInfo = {
Expand Down Expand Up @@ -325,7 +327,7 @@ class BasicToolOperation extends EventListener {
this.eventUnbinding();
}

public createCanvas(size: ISize) {
public createCanvas(size: ISize, isAppend = true) {
// TODO 后续需要将 canvas 抽离出来,迭代器叠加
const basicCanvas = document.createElement('canvas');
const pixel = this.pixelRatio;
Expand All @@ -351,12 +353,17 @@ class BasicToolOperation extends EventListener {
canvas.width = size.width * pixel;
canvas.height = size.height * pixel;

if (this.container.hasChildNodes()) {
this.container.insertBefore(canvas, this.container.childNodes[0]);
this.container.insertBefore(basicCanvas, this.container.childNodes[0]);
} else {
this.container.appendChild(basicCanvas);
this.container.appendChild(canvas);
// set Attribute
this.container.style.position = 'relative';

if (isAppend) {
if (this.container.hasChildNodes()) {
this.container.insertBefore(canvas, this.container.childNodes[0]);
this.container.insertBefore(basicCanvas, this.container.childNodes[0]);
} else {
this.container.appendChild(basicCanvas);
this.container.appendChild(canvas);
}
}

this.canvas = canvas;
Expand Down Expand Up @@ -515,7 +522,7 @@ class BasicToolOperation extends EventListener {
this.renderBasicCanvas();

this.emit('dependRender');
this.emit('renderZoom', zoom);
this.emit('renderZoom', zoom, currentPos);
};

/**
Expand Down Expand Up @@ -903,7 +910,7 @@ class BasicToolOperation extends EventListener {
this.currentPosStorage = newCurrentPos;
this.imgInfo = imgInfo;
zoomInfo.ratio = ratio;
this.emit('renderZoom', zoom, currentPos);
this.emit('renderZoom', zoom, newCurrentPos);
};

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/*
* @Author: Laoluo luozefeng@sensetime.com
* @Date: 2022-01-12 13:15:33
* @LastEditors: Laoluo luozefeng@sensetime.com
* @LastEditTime: 2022-06-27 17:34:35
*/
export default class EventListener {
private _events: Map<string, any[]>;

Expand All @@ -10,7 +16,7 @@ export default class EventListener {
* @param eventName 事件名字
* @param callback 事件回调
*/
public on(eventName: string, callback: (params?: any) => void) {
public on(eventName: string, callback: (...args: any[]) => void) {
const existEvents = this._events.get(eventName) || [];
if (!existEvents.some((fn) => fn === callback)) {
this._events.set(eventName, existEvents.concat(callback));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,8 @@ class PolygonOperation extends BasicToolOperation {

polygonList.push(newPolygon);

this.emit('polygonCreated', newPolygon, this.zoom, this.currentPos);

this.setSelectedIdAfterAddingDrawing(id);
}

Expand Down
2 changes: 2 additions & 0 deletions packages/lb-annotation/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,5 @@ export {
AnnotationEngine,
PointCloud,
};

export * from './newCore';
55 changes: 55 additions & 0 deletions packages/lb-annotation/src/newCore/CanvasSchduler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Canvas Schduler
* @Author: Laoluo luozefeng@sensetime.com
* @Date: 2022-06-22 14:59:33
* @LastEditors: Laoluo luozefeng@sensetime.com
* @LastEditTime: 2022-06-27 16:57:59
*/
interface ICanvasBasicOperation {
createCanvas(id: string, options?: { size?: { width: number; height: number } }): HTMLCanvasElement;
createCanvas(canvas: HTMLCanvasElement): HTMLCanvasElement;
destroyCanvas(id: string): HTMLElement | null;
}

interface ICavnasSchdulerProps {
container: HTMLElement;
}

class CanvasSchduler implements ICanvasBasicOperation {
private container: HTMLElement;

constructor(props: ICavnasSchdulerProps) {
this.container = props.container;
}

public createCanvas(id: string | HTMLCanvasElement, options?: { size?: { width: number; height: number } }) {
if (typeof id !== 'string') {
this.container.appendChild(id);
id.style.position = 'absolute';
id.style.left = '0';
id.style.top = '0';
return id;
}

const canvas = document.createElement('canvas');
canvas.id = id;
if (options && options.size) {
canvas.width = options.size.width;
canvas.height = options.size.height;
}

this.container.appendChild(canvas);

return canvas;
}

public destroyCanvas(id: string) {
const dom = document.getElementById(id);
if (dom) {
this.container.removeChild(dom);
}
return dom;
}
}

export { CanvasSchduler };
8 changes: 8 additions & 0 deletions packages/lb-annotation/src/newCore/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* @Author: Laoluo luozefeng@sensetime.com
* @Date: 2022-06-22 14:58:48
* @LastEditors: Laoluo luozefeng@sensetime.com
* @LastEditTime: 2022-06-22 15:29:37
*/

export * from './CanvasSchduler';
Loading

0 comments on commit 5220663

Please sign in to comment.