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 { 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);

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
// 测试代码