Optmi renderer model
This commit is contained in:
parent
8ced3d82f3
commit
ed8269ff50
@ -1,5 +1,4 @@
|
||||
import { AbstractRenderer, IRendererParam } from "@Model/Renderer";
|
||||
import { IAnyObject } from "@Model/Model";
|
||||
import { EventType } from "@Model/Emitter";
|
||||
import { GLCanvas, GLCanvasOption } from "./GLCanvas";
|
||||
import { GLContext } from "./GLContext";
|
||||
@ -17,19 +16,13 @@ type IRendererParams = IRendererOwnParams & GLCanvasOption;
|
||||
|
||||
abstract class BasicRenderer<
|
||||
P extends IRendererParam = {},
|
||||
M extends IAnyObject = {},
|
||||
E extends Record<EventType, any> = {}
|
||||
> extends AbstractRenderer<P, M & IRendererParams, E & {loop: number}> {
|
||||
> extends AbstractRenderer<P, E & {loop: number}> {
|
||||
|
||||
public get dom() {
|
||||
return this.canvas.dom
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染器参数
|
||||
*/
|
||||
public param: Partial<M & IRendererParams> = {};
|
||||
|
||||
/**
|
||||
* 使用的画布
|
||||
*/
|
||||
@ -45,19 +38,16 @@ abstract class BasicRenderer<
|
||||
*/
|
||||
protected clock: Clock;
|
||||
|
||||
public constructor(param: Partial<M & IRendererParams> = {}) {
|
||||
public constructor() {
|
||||
super();
|
||||
|
||||
// 初始化参数
|
||||
this.param = {
|
||||
autoResize: param.autoResize ?? true,
|
||||
mouseEvent: param.autoResize ?? true,
|
||||
eventLog: param.eventLog ?? false,
|
||||
className: param.className ?? ""
|
||||
} as M & IRendererParams;
|
||||
|
||||
// 实例化画布对象
|
||||
this.canvas = new GLCanvas(param.canvas, this.param);
|
||||
this.canvas = new GLCanvas(undefined, {
|
||||
autoResize: true,
|
||||
mouseEvent: true,
|
||||
eventLog: false,
|
||||
className: "canvas"
|
||||
});
|
||||
|
||||
// 实例化摄像机
|
||||
this.camera = new Camera(this.canvas);
|
||||
|
@ -1,28 +1,40 @@
|
||||
import { ObjectData, ICommonParam } from "@Model/Renderer";
|
||||
import { ObjectData } from "@Model/Renderer";
|
||||
import { ObjectID } from "@Model/Model";
|
||||
import { IParameterValue, getDefaultValue } from "@Model/Parameter";
|
||||
import { BasicRenderer } from "./BasicRenderer";
|
||||
import { BasicsShader } from "./BasicShader";
|
||||
import { Axis } from "./Axis";
|
||||
import { BasicCube } from "./BasicCube";
|
||||
import { GroupShader } from "./GroupShader";
|
||||
import { BasicGroup } from "./BasicGroup";
|
||||
import DisplayObject from "./DisplayObject";
|
||||
|
||||
interface IClassicRendererParams {
|
||||
point: {
|
||||
size: number;
|
||||
}
|
||||
cube: {
|
||||
radius: number[];
|
||||
}
|
||||
}
|
||||
import { DisplayObject } from "./DisplayObject";
|
||||
|
||||
enum MouseMod {
|
||||
Drag = 1,
|
||||
click = 2
|
||||
}
|
||||
|
||||
class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> {
|
||||
type IClassicRendererParameter = {
|
||||
renderer: {};
|
||||
points: {
|
||||
color: "color",
|
||||
size: "number"
|
||||
};
|
||||
cube: {
|
||||
color: "color"
|
||||
};
|
||||
}
|
||||
|
||||
class ClassicRenderer extends BasicRenderer<IClassicRendererParameter> {
|
||||
|
||||
public override rendererParameterOption = {};
|
||||
public override pointsParameterOption = {
|
||||
color: { type: "color", name: "" },
|
||||
size: { type: "number", name: "Common.Attr.Key.Size" }
|
||||
};
|
||||
public override cubeParameterOption = {
|
||||
color: { type: "color", name: "" },
|
||||
};
|
||||
|
||||
private basicShader: BasicsShader = undefined as any;
|
||||
private axisObject: Axis = undefined as any;
|
||||
@ -52,6 +64,8 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> {
|
||||
}
|
||||
|
||||
public onLoad(): this {
|
||||
|
||||
this.rendererParameter = getDefaultValue(this.rendererParameterOption);
|
||||
|
||||
// 自动调节分辨率
|
||||
this.autoResize();
|
||||
@ -188,7 +202,7 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> {
|
||||
|
||||
points(
|
||||
id: ObjectID, position?: ObjectData,
|
||||
param?: Readonly<Partial<ICommonParam & IClassicRendererParams["point"]>>
|
||||
param?: Readonly<IParameterValue<IClassicRendererParameter["points"]>>
|
||||
): this {
|
||||
let object = this.objectPool.get(id);
|
||||
let group: BasicGroup;
|
||||
@ -236,8 +250,8 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> {
|
||||
}
|
||||
|
||||
cube(
|
||||
id: ObjectID, position?: ObjectData,
|
||||
param?: Readonly<Partial<ICommonParam & IClassicRendererParams["cube"]>>
|
||||
id: ObjectID, position?: ObjectData, radius?: ObjectData,
|
||||
param?: Readonly<IParameterValue<IClassicRendererParameter["cube"]>>
|
||||
): this {
|
||||
let object = this.objectPool.get(id);
|
||||
let cube: BasicCube;
|
||||
@ -251,6 +265,13 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> {
|
||||
cube.position[1] = position[1] ?? cube.position[1];
|
||||
cube.position[2] = position[2] ?? cube.position[2];
|
||||
}
|
||||
|
||||
if (radius) {
|
||||
cube.r[0] = radius[0] ?? cube.r[0];
|
||||
cube.r[1] = radius[1] ?? cube.r[1];
|
||||
cube.r[2] = radius[2] ?? cube.r[2];
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new Error("Renderer: Use duplicate ObjectID when drawing different types of objects");
|
||||
}
|
||||
@ -264,6 +285,12 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> {
|
||||
cube.position[2] = position[2] ?? cube.position[2];
|
||||
}
|
||||
|
||||
if (radius) {
|
||||
cube.r[0] = radius[0] ?? cube.r[0];
|
||||
cube.r[1] = radius[1] ?? cube.r[1];
|
||||
cube.r[2] = radius[2] ?? cube.r[2];
|
||||
}
|
||||
|
||||
this.objectPool.set(id, cube);
|
||||
console.log(`Renderer: Create new cube object with id ${id}`);
|
||||
}
|
||||
@ -272,21 +299,11 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> {
|
||||
cube.isDraw = true;
|
||||
|
||||
// 参数传递
|
||||
if (param) {
|
||||
if (param && param.color) {
|
||||
|
||||
// 颜色数据
|
||||
if (param.color) {
|
||||
cube.color[0] = param.color[0] ?? cube.color[0]
|
||||
cube.color[1] = param.color[1] ?? cube.color[1]
|
||||
cube.color[2] = param.color[2] ?? cube.color[2]
|
||||
}
|
||||
|
||||
// 半径数据
|
||||
if (param.radius) {
|
||||
cube.r[0] = param.radius[0] ?? cube.r[0];
|
||||
cube.r[1] = param.radius[1] ?? cube.r[1];
|
||||
cube.r[2] = param.radius[2] ?? cube.r[2];
|
||||
}
|
||||
cube.color[0] = param.color[0] ?? cube.color[0];
|
||||
cube.color[1] = param.color[1] ?? cube.color[1];
|
||||
cube.color[2] = param.color[2] ?? cube.color[2];
|
||||
}
|
||||
|
||||
return this;
|
||||
|
@ -369,9 +369,8 @@ class Model extends Emitter<ModelEvent> {
|
||||
} as any);
|
||||
}
|
||||
if (object.display && object instanceof Range) {
|
||||
this.renderer.cube(object.id, object.position, {
|
||||
color: object.color,
|
||||
radius: object.radius
|
||||
this.renderer.cube(object.id, object.position, object.radius, {
|
||||
color: object.color
|
||||
} as any);
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,31 @@
|
||||
import { Emitter, EventType } from "@Model/Emitter";
|
||||
import { IAnyObject, ObjectID } from "@Model/Model";
|
||||
import { IParameter, IParameterOption, IParameterValue } from "@Model/Parameter";
|
||||
|
||||
/**
|
||||
* 默认类型
|
||||
*/
|
||||
type IDefaultType<T, D> = T extends undefined ? D : T;
|
||||
|
||||
/**
|
||||
* 渲染器参数
|
||||
*/
|
||||
interface IRendererParam {
|
||||
|
||||
/**
|
||||
* 渲染器参数
|
||||
*/
|
||||
renderer?: IParameter;
|
||||
|
||||
/**
|
||||
* 绘制点需要的参数
|
||||
*/
|
||||
points?: IAnyObject
|
||||
points?: IParameter;
|
||||
|
||||
/**
|
||||
* 绘制立方体需要的参数
|
||||
*/
|
||||
cube?: IAnyObject
|
||||
cube?: IParameter;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -35,12 +46,8 @@ interface ICommonParam {
|
||||
*/
|
||||
type ObjectData = Array<number> | Float32Array;
|
||||
|
||||
interface IRendererConstructor<
|
||||
M extends IAnyObject = {}
|
||||
> {
|
||||
new (canvas: HTMLCanvasElement, param?: M): AbstractRenderer<
|
||||
IRendererParam, IAnyObject, AbstractRendererEvent
|
||||
>
|
||||
interface IRendererConstructor {
|
||||
new (): AbstractRenderer<IRendererParam, AbstractRendererEvent>
|
||||
}
|
||||
|
||||
type AbstractRendererEvent = {
|
||||
@ -56,7 +63,6 @@ type AbstractRendererEvent = {
|
||||
*/
|
||||
abstract class AbstractRenderer<
|
||||
P extends IRendererParam = {},
|
||||
M extends IAnyObject = {},
|
||||
E extends AbstractRendererEvent = {loop: number}
|
||||
> extends Emitter<E> {
|
||||
|
||||
@ -65,28 +71,17 @@ abstract class AbstractRenderer<
|
||||
/**
|
||||
* 渲染器参数
|
||||
*/
|
||||
abstract param: Partial<M>;
|
||||
public rendererParameterOption: IParameterOption<IDefaultType<P["renderer"], {}>> = {} as any;
|
||||
public pointsParameterOption: IParameterOption<IDefaultType<P["points"], {}>> = {} as any;
|
||||
public cubeParameterOption: IParameterOption<IDefaultType<P["cube"], {}>> = {} as any;
|
||||
|
||||
/**
|
||||
* 类型断言
|
||||
* 渲染器参数
|
||||
*/
|
||||
get isRenderer() {
|
||||
return true;
|
||||
}
|
||||
public rendererParameter: IParameterValue<IDefaultType<P["renderer"], {}>> = {} as any;
|
||||
|
||||
/**
|
||||
* 断言对象是否是渲染器
|
||||
*/
|
||||
public static isRenderer(render: any): render is AbstractRenderer {
|
||||
if (render instanceof Object) {
|
||||
return !!(render as AbstractRenderer).isRenderer;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @function start
|
||||
* @function clean
|
||||
* 开始一次数据更新 \
|
||||
* 此函数将清除固定对象的绘制状态 \
|
||||
* 在每次数据更新前调用 \
|
||||
@ -103,7 +98,9 @@ abstract class AbstractRenderer<
|
||||
* @param id 使用的标识符
|
||||
* @param position 做标集合
|
||||
*/
|
||||
abstract points(id: ObjectID, position?: ObjectData, param?: Readonly<P["points"] & ICommonParam>): this;
|
||||
abstract points(id: ObjectID, position?: ObjectData, param?:
|
||||
Readonly<IParameterValue<IDefaultType<P["points"], {}>>>
|
||||
): this;
|
||||
|
||||
/**
|
||||
* @function cube 绘制立方体
|
||||
@ -113,7 +110,9 @@ abstract class AbstractRenderer<
|
||||
*
|
||||
* 注意: 这里的半径指的是立方体重心与立方体任意一面几何中心的距离
|
||||
*/
|
||||
abstract cube(id: ObjectID, position?: ObjectData, param?: Readonly<P["cube"] & ICommonParam>): this;
|
||||
abstract cube(id: ObjectID, position?: ObjectData, radius?: ObjectData, param?:
|
||||
Readonly<IParameterValue<IDefaultType<P["cube"], {}>>>
|
||||
): this;
|
||||
}
|
||||
|
||||
export default AbstractRenderer;
|
||||
|
@ -21,7 +21,7 @@ class Laboratory extends Component {
|
||||
throw new Error("Laboratory: 重复引用 canvas 节点");
|
||||
}
|
||||
|
||||
const renderer = new ClassicRenderer({ className: "canvas" }).onLoad();
|
||||
const renderer = new ClassicRenderer().onLoad();
|
||||
this.canvasContRef.current.appendChild(renderer.canvas.dom);
|
||||
|
||||
let model = new Model().bindRenderer(renderer);
|
||||
@ -51,10 +51,12 @@ class Laboratory extends Component {
|
||||
});
|
||||
renderer.points("2");
|
||||
renderer.cube("4");
|
||||
renderer.cube("5", new Array(3).fill(0).map(() => (Math.random() - .5) * 2), {
|
||||
radius: new Array(3).fill(0).map(() => Math.random() * 1.2),
|
||||
color: [1, 1, 0]
|
||||
})
|
||||
renderer.cube("5",
|
||||
new Array(3).fill(0).map(() => (Math.random() - .5) * 2),
|
||||
new Array(3).fill(0).map(() => Math.random() * 1.2), {
|
||||
color: [1, 1, 0]
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
(window as any).renderer = renderer;
|
||||
|
@ -35,9 +35,9 @@ class SimulatorWeb extends Component {
|
||||
(window as any).setting = (this.setting as any);
|
||||
|
||||
// TODO: 这里要读取存档
|
||||
const classicRender = new ClassicRenderer().onLoad();
|
||||
this.status = new Status();
|
||||
this.status.renderer = new ClassicRenderer({ className: "canvas" }).onLoad();
|
||||
this.status.bindRenderer(this.status.renderer);
|
||||
this.status.bindRenderer(classicRender);
|
||||
this.status.setting = this.setting;
|
||||
|
||||
// 测试代码
|
||||
|
Loading…
Reference in New Issue
Block a user