Add module render update

This commit is contained in:
2022-02-21 17:25:43 +08:00
parent 5148314ddc
commit 3e9b60f598
6 changed files with 191 additions and 28 deletions
+20 -1
View File
@@ -38,13 +38,32 @@ abstract class Behavior<
*/
abstract parameter?: P;
/**
* 全部影响作用前
* @param individual 影响个体
* @param group 影响组
* @param model 模型
* @param t 经过时间
*/
public beforeEffect(individual: Individual, group: Group, model: Model, t: number): void {};
/**
* 作用影响于个体
* @param individual 影响个体
* @param group 影响组
* @param model 模型
* @param t 经过时间
*/
abstract effect(individual: Individual, group: Group, model: Model, t: number): void;
public effect(individual: Individual, group: Group, model: Model, t: number): void {};
/**
* 全部影响作用后
* @param individual 影响个体
* @param group 影响组
* @param model 模型
* @param t 经过时间
*/
public afterEffect(individual: Individual, group: Group, model: Model, t: number): void {};
}
+22
View File
@@ -7,6 +7,21 @@ import type { ObjectID } from "./Renderer";
*/
class CtrlObject extends LabelObject {
/**
* 颜色
*/
public color: number[] = [.5, .5, .5];
/**
* 是否显示
*/
public display: boolean = true;
/**
* 是否更新
*/
public update: boolean = true;
/**
* 唯一标识符
*/
@@ -25,6 +40,13 @@ class CtrlObject extends LabelObject {
this.model = model;
this.id = id;
}
/**
* 移除
*/
public delete() {
this.model.deleteObject([this]);
}
}
export default CtrlObject;
+23 -2
View File
@@ -37,9 +37,11 @@ class Group extends CtrlObject {
public add(individual: Individual[] | Individual): this {
if (Array.isArray(individual)) {
for (let i = 0; i < individual.length; i++) {
individual[i].group = this;
this.individuals.add(individual[i]);
}
} else {
individual.group = this;
this.individuals.add(individual);
}
return this;
@@ -112,13 +114,32 @@ class Group extends CtrlObject {
* 执行行为影响
* @param
*/
public runner(t: number): void {
public runner(t: number, effectType: "beforeEffect" | "effect" | "afterEffect" ): void {
this.individuals.forEach((individual) => {
for(let j = 0; j < this.behaviors.length; j++) {
this.behaviors[j].effect(individual, this, this.model, t);
this.behaviors[j][effectType](individual, this, this.model, t);
}
});
}
/**
* 导出坐标数据
*/
public exportPositionData(): Float32Array {
let index = 0;
let dataBuffer = new Float32Array(this.individuals.size * 3);
this.individuals.forEach((individual) => {
dataBuffer[index ++] = individual.position[0];
dataBuffer[index ++] = individual.position[1];
dataBuffer[index ++] = individual.position[2];
});
return dataBuffer;
}
/**
* 绘制大小
*/
public size: number = 60;
}
export default Group;
+108 -20
View File
@@ -1,13 +1,17 @@
import { Individual } from "./Individual";
import { Group } from "./Group";
import { Range } from "./Range";
import { Emitter, EventType, EventMixin } from "./Emitter";
import { CtrlObject } from "./CtrlObject";
import { ObjectID } from "./Renderer";
import { ObjectID, AbstractRenderer } from "./Renderer";
type ModelEvent = {
addGroup: Group;
deleteGroup: Group[];
groupAdd: Group;
rangeAdd: Range;
objectAdd: CtrlObject;
objectDelete: CtrlObject[];
objectChange: CtrlObject[];
};
/**
@@ -31,43 +35,127 @@ class Model extends Emitter<ModelEvent> {
/**
* 添加组
*/
public addGroup(): void {
public addGroup(): Group {
console.log(`Model: Creat group with id ${this.idIndex}`);
let group = new Group(this, this.nextId);
this.objectPool.push(group);
this.emit("addGroup", group);
this.emit("groupAdd", group);
this.emit("objectAdd", group);
this.emit("objectChange", this.objectPool);
return group;
}
/**
* 删除组
* 添加范围
*/
public deleteGroup(groups: Group[] | ObjectID[]): void {
let deletedGroups: Group[] = [];
this.objectPool = this.objectPool.filter((object) => {
if (!(object instanceof Group)) return true;
let deletedGroup: Group | undefined;
public addRange(): Range {
console.log(`Model: Creat range with id ${this.idIndex}`);
let range = new Range(this, this.nextId);
this.objectPool.push(range);
this.emit("rangeAdd", range);
this.emit("objectAdd", range);
this.emit("objectChange", this.objectPool);
return range;
}
for (let i = 0; i < groups.length; i++) {
if (groups[i] instanceof Group) {
if (groups[i] === object) {
deletedGroup = object;
/**
* 删除对象
*/
public deleteObject(object: CtrlObject[] | ObjectID[]): CtrlObject[] {
let deletedObject: CtrlObject[] = [];
this.objectPool = this.objectPool.filter((currentObject) => {
let needDeleted: boolean = false;
for (let i = 0; i < object.length; i++) {
if (object[i] instanceof CtrlObject) {
if (object[i] === currentObject) {
needDeleted = true;
}
} else {
if (groups[i] === object.id) {
deletedGroup = object;
if (object[i] == currentObject.id) {
needDeleted = true;
}
}
}
if (deletedGroup) {
deletedGroups.push(deletedGroup);
if (needDeleted) {
deletedObject.push(currentObject);
return false;
} else {
return true;
}
});
this.emit("deleteGroup", deletedGroups);
if (deletedObject.length) {
console.log(`Model: Delete object ${deletedObject.map((object) => object.id).join(", ")}`);
this.emit("objectDelete", deletedObject);
this.emit("objectChange", this.objectPool);
}
return deletedObject;
}
/**
* 渲染器
*/
public renderer: AbstractRenderer = undefined as any;
/**
* 绑定渲染器
* @param renderer 渲染器
*/
public bindRenderer(renderer: AbstractRenderer): this {
this.renderer = renderer;
return this;
}
/**
* 更新渲染数据
*/
public update(t: number) {
// 清除全部渲染状态
this.renderer.clean();
// 第一轮更新
for (let i = 0; i < this.objectPool.length; i++) {
let object = this.objectPool[i];
if (object instanceof Group && object.update) {
object.runner(t, "beforeEffect");
}
}
// 第二轮更新
for (let i = 0; i < this.objectPool.length; i++) {
let object = this.objectPool[i];
if (object instanceof Group && object.update) {
object.runner(t, "effect");
}
}
// 第三轮更新
for (let i = 0; i < this.objectPool.length; i++) {
let object = this.objectPool[i];
if (object instanceof Group && object.update) {
object.runner(t, "afterEffect");
}
}
// 渲染
for (let i = 0; i < this.objectPool.length; i++) {
let object = this.objectPool[i];
if (object.display && object instanceof Group) {
this.renderer.points(object.id, object.exportPositionData(), {
color: object.color,
size: object.size
} as any);
}
if (object.display && object instanceof Range) {
this.renderer.cube(object.id, object.position, {
color: object.color,
radius: object.radius
} as any);
}
}
}
}
+5
View File
@@ -10,6 +10,11 @@ class Range extends CtrlObject {
*/
public position: number[] = [];
/**
* 半径
*/
public radius: number[] = [1, 1, 1];
}
export default Range;