Optmi renderer model & renderer shape parameter #38
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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),
|
||||||
color: [1, 1, 0]
|
new Array(3).fill(0).map(() => Math.random() * 1.2), {
|
||||||
})
|
color: [1, 1, 0]
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
(window as any).renderer = renderer;
|
(window as any).renderer = renderer;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
// 测试代码
|
// 测试代码
|
||||||
|
Loading…
Reference in New Issue
Block a user