Optmi renderer model

This commit is contained in:
MrKBear 2022-04-09 15:07:45 +08:00
parent 8ced3d82f3
commit ed8269ff50
6 changed files with 92 additions and 85 deletions

View File

@ -1,5 +1,4 @@
import { AbstractRenderer, IRendererParam } from "@Model/Renderer"; import { AbstractRenderer, IRendererParam } from "@Model/Renderer";
import { IAnyObject } from "@Model/Model";
import { EventType } from "@Model/Emitter"; import { EventType } from "@Model/Emitter";
import { GLCanvas, GLCanvasOption } from "./GLCanvas"; import { GLCanvas, GLCanvasOption } from "./GLCanvas";
import { GLContext } from "./GLContext"; import { GLContext } from "./GLContext";
@ -17,19 +16,13 @@ type IRendererParams = IRendererOwnParams & GLCanvasOption;
abstract class BasicRenderer< abstract class BasicRenderer<
P extends IRendererParam = {}, P extends IRendererParam = {},
M extends IAnyObject = {},
E extends Record<EventType, any> = {} E extends Record<EventType, any> = {}
> extends AbstractRenderer<P, M & IRendererParams, E & {loop: number}> { > extends AbstractRenderer<P, E & {loop: number}> {
public get dom() { public get dom() {
return this.canvas.dom return this.canvas.dom
} }
/**
*
*/
public param: Partial<M & IRendererParams> = {};
/** /**
* 使 * 使
*/ */
@ -45,19 +38,16 @@ abstract class BasicRenderer<
*/ */
protected clock: Clock; protected clock: Clock;
public constructor(param: Partial<M & IRendererParams> = {}) { public constructor() {
super(); 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); this.camera = new Camera(this.canvas);

View File

@ -1,28 +1,40 @@
import { ObjectData, ICommonParam } from "@Model/Renderer"; import { ObjectData } from "@Model/Renderer";
import { ObjectID } from "@Model/Model"; import { ObjectID } from "@Model/Model";
import { IParameterValue, getDefaultValue } from "@Model/Parameter";
import { BasicRenderer } from "./BasicRenderer"; import { BasicRenderer } from "./BasicRenderer";
import { BasicsShader } from "./BasicShader"; import { BasicsShader } from "./BasicShader";
import { Axis } from "./Axis"; import { Axis } from "./Axis";
import { BasicCube } from "./BasicCube"; import { BasicCube } from "./BasicCube";
import { GroupShader } from "./GroupShader"; import { GroupShader } from "./GroupShader";
import { BasicGroup } from "./BasicGroup"; import { BasicGroup } from "./BasicGroup";
import DisplayObject from "./DisplayObject"; import { DisplayObject } from "./DisplayObject";
interface IClassicRendererParams {
point: {
size: number;
}
cube: {
radius: number[];
}
}
enum MouseMod { enum MouseMod {
Drag = 1, Drag = 1,
click = 2 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 basicShader: BasicsShader = undefined as any;
private axisObject: Axis = undefined as any; private axisObject: Axis = undefined as any;
@ -53,6 +65,8 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> {
public onLoad(): this { public onLoad(): this {
this.rendererParameter = getDefaultValue(this.rendererParameterOption);
// 自动调节分辨率 // 自动调节分辨率
this.autoResize(); this.autoResize();
@ -188,7 +202,7 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> {
points( points(
id: ObjectID, position?: ObjectData, id: ObjectID, position?: ObjectData,
param?: Readonly<Partial<ICommonParam & IClassicRendererParams["point"]>> param?: Readonly<IParameterValue<IClassicRendererParameter["points"]>>
): this { ): this {
let object = this.objectPool.get(id); let object = this.objectPool.get(id);
let group: BasicGroup; let group: BasicGroup;
@ -236,8 +250,8 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> {
} }
cube( cube(
id: ObjectID, position?: ObjectData, id: ObjectID, position?: ObjectData, radius?: ObjectData,
param?: Readonly<Partial<ICommonParam & IClassicRendererParams["cube"]>> param?: Readonly<IParameterValue<IClassicRendererParameter["cube"]>>
): this { ): this {
let object = this.objectPool.get(id); let object = this.objectPool.get(id);
let cube: BasicCube; let cube: BasicCube;
@ -251,6 +265,13 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> {
cube.position[1] = position[1] ?? cube.position[1]; cube.position[1] = position[1] ?? cube.position[1];
cube.position[2] = position[2] ?? cube.position[2]; 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 { } else {
throw new Error("Renderer: Use duplicate ObjectID when drawing different types of objects"); 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]; 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); this.objectPool.set(id, cube);
console.log(`Renderer: Create new cube object with id ${id}`); console.log(`Renderer: Create new cube object with id ${id}`);
} }
@ -272,21 +299,11 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> {
cube.isDraw = true; cube.isDraw = true;
// 参数传递 // 参数传递
if (param) { if (param && param.color) {
// 颜色数据 cube.color[0] = param.color[0] ?? cube.color[0];
if (param.color) { cube.color[1] = param.color[1] ?? cube.color[1];
cube.color[0] = param.color[0] ?? cube.color[0] cube.color[2] = param.color[2] ?? cube.color[2];
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];
}
} }
return this; return this;

View File

@ -369,9 +369,8 @@ class Model extends Emitter<ModelEvent> {
} as any); } as any);
} }
if (object.display && object instanceof Range) { if (object.display && object instanceof Range) {
this.renderer.cube(object.id, object.position, { this.renderer.cube(object.id, object.position, object.radius, {
color: object.color, color: object.color
radius: object.radius
} as any); } as any);
} }
} }

View File

@ -1,20 +1,31 @@
import { Emitter, EventType } from "@Model/Emitter"; import { Emitter, EventType } from "@Model/Emitter";
import { IAnyObject, ObjectID } from "@Model/Model"; import { IAnyObject, ObjectID } from "@Model/Model";
import { IParameter, IParameterOption, IParameterValue } from "@Model/Parameter";
/**
*
*/
type IDefaultType<T, D> = T extends undefined ? D : T;
/** /**
* *
*/ */
interface IRendererParam { interface IRendererParam {
/**
*
*/
renderer?: IParameter;
/** /**
* *
*/ */
points?: IAnyObject points?: IParameter;
/** /**
* *
*/ */
cube?: IAnyObject cube?: IParameter;
} }
/** /**
@ -35,12 +46,8 @@ interface ICommonParam {
*/ */
type ObjectData = Array<number> | Float32Array; type ObjectData = Array<number> | Float32Array;
interface IRendererConstructor< interface IRendererConstructor {
M extends IAnyObject = {} new (): AbstractRenderer<IRendererParam, AbstractRendererEvent>
> {
new (canvas: HTMLCanvasElement, param?: M): AbstractRenderer<
IRendererParam, IAnyObject, AbstractRendererEvent
>
} }
type AbstractRendererEvent = { type AbstractRendererEvent = {
@ -56,7 +63,6 @@ type AbstractRendererEvent = {
*/ */
abstract class AbstractRenderer< abstract class AbstractRenderer<
P extends IRendererParam = {}, P extends IRendererParam = {},
M extends IAnyObject = {},
E extends AbstractRendererEvent = {loop: number} E extends AbstractRendererEvent = {loop: number}
> extends Emitter<E> { > 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() { public rendererParameter: IParameterValue<IDefaultType<P["renderer"], {}>> = {} as any;
return true;
}
/** /**
* * @function clean
*/
public static isRenderer(render: any): render is AbstractRenderer {
if (render instanceof Object) {
return !!(render as AbstractRenderer).isRenderer;
} else {
return false;
}
};
/**
* @function start
* \ * \
* \ * \
* \ * \
@ -103,7 +98,9 @@ abstract class AbstractRenderer<
* @param id 使 * @param id 使
* @param position * @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 * @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; export default AbstractRenderer;

View File

@ -21,7 +21,7 @@ class Laboratory extends Component {
throw new Error("Laboratory: 重复引用 canvas 节点"); throw new Error("Laboratory: 重复引用 canvas 节点");
} }
const renderer = new ClassicRenderer({ className: "canvas" }).onLoad(); const renderer = new ClassicRenderer().onLoad();
this.canvasContRef.current.appendChild(renderer.canvas.dom); this.canvasContRef.current.appendChild(renderer.canvas.dom);
let model = new Model().bindRenderer(renderer); let model = new Model().bindRenderer(renderer);
@ -51,10 +51,12 @@ class Laboratory extends Component {
}); });
renderer.points("2"); renderer.points("2");
renderer.cube("4"); renderer.cube("4");
renderer.cube("5", new Array(3).fill(0).map(() => (Math.random() - .5) * 2), { renderer.cube("5",
radius: new Array(3).fill(0).map(() => Math.random() * 1.2), new Array(3).fill(0).map(() => (Math.random() - .5) * 2),
new Array(3).fill(0).map(() => Math.random() * 1.2), {
color: [1, 1, 0] color: [1, 1, 0]
}) }
)
} }
(window as any).renderer = renderer; (window as any).renderer = renderer;

View File

@ -35,9 +35,9 @@ class SimulatorWeb extends Component {
(window as any).setting = (this.setting as any); (window as any).setting = (this.setting as any);
// TODO: 这里要读取存档 // TODO: 这里要读取存档
const classicRender = new ClassicRenderer().onLoad();
this.status = new Status(); this.status = new Status();
this.status.renderer = new ClassicRenderer({ className: "canvas" }).onLoad(); this.status.bindRenderer(classicRender);
this.status.bindRenderer(this.status.renderer);
this.status.setting = this.setting; this.status.setting = this.setting;
// 测试代码 // 测试代码