Add module render update
This commit is contained in:
parent
5148314ddc
commit
3e9b60f598
@ -38,13 +38,32 @@ abstract class Behavior<
|
|||||||
*/
|
*/
|
||||||
abstract parameter?: P;
|
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 individual 影响个体
|
||||||
* @param group 影响组
|
* @param group 影响组
|
||||||
|
* @param model 模型
|
||||||
* @param t 经过时间
|
* @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 {};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,21 @@ import type { ObjectID } from "./Renderer";
|
|||||||
*/
|
*/
|
||||||
class CtrlObject extends LabelObject {
|
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.model = model;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除
|
||||||
|
*/
|
||||||
|
public delete() {
|
||||||
|
this.model.deleteObject([this]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CtrlObject;
|
export default CtrlObject;
|
||||||
|
@ -37,9 +37,11 @@ class Group extends CtrlObject {
|
|||||||
public add(individual: Individual[] | Individual): this {
|
public add(individual: Individual[] | Individual): this {
|
||||||
if (Array.isArray(individual)) {
|
if (Array.isArray(individual)) {
|
||||||
for (let i = 0; i < individual.length; i++) {
|
for (let i = 0; i < individual.length; i++) {
|
||||||
|
individual[i].group = this;
|
||||||
this.individuals.add(individual[i]);
|
this.individuals.add(individual[i]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
individual.group = this;
|
||||||
this.individuals.add(individual);
|
this.individuals.add(individual);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
@ -112,13 +114,32 @@ class Group extends CtrlObject {
|
|||||||
* 执行行为影响
|
* 执行行为影响
|
||||||
* @param
|
* @param
|
||||||
*/
|
*/
|
||||||
public runner(t: number): void {
|
public runner(t: number, effectType: "beforeEffect" | "effect" | "afterEffect" ): void {
|
||||||
this.individuals.forEach((individual) => {
|
this.individuals.forEach((individual) => {
|
||||||
for(let j = 0; j < this.behaviors.length; j++) {
|
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;
|
export default Group;
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
|
|
||||||
import { Individual } from "./Individual";
|
import { Individual } from "./Individual";
|
||||||
import { Group } from "./Group";
|
import { Group } from "./Group";
|
||||||
|
import { Range } from "./Range";
|
||||||
import { Emitter, EventType, EventMixin } from "./Emitter";
|
import { Emitter, EventType, EventMixin } from "./Emitter";
|
||||||
import { CtrlObject } from "./CtrlObject";
|
import { CtrlObject } from "./CtrlObject";
|
||||||
import { ObjectID } from "./Renderer";
|
import { ObjectID, AbstractRenderer } from "./Renderer";
|
||||||
|
|
||||||
type ModelEvent = {
|
type ModelEvent = {
|
||||||
addGroup: Group;
|
groupAdd: Group;
|
||||||
deleteGroup: 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}`);
|
console.log(`Model: Creat group with id ${this.idIndex}`);
|
||||||
let group = new Group(this, this.nextId);
|
let group = new Group(this, this.nextId);
|
||||||
this.objectPool.push(group);
|
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 {
|
public addRange(): Range {
|
||||||
let deletedGroups: Group[] = [];
|
console.log(`Model: Creat range with id ${this.idIndex}`);
|
||||||
this.objectPool = this.objectPool.filter((object) => {
|
let range = new Range(this, this.nextId);
|
||||||
if (!(object instanceof Group)) return true;
|
this.objectPool.push(range);
|
||||||
let deletedGroup: Group | undefined;
|
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 {
|
} else {
|
||||||
if (groups[i] === object.id) {
|
if (object[i] == currentObject.id) {
|
||||||
deletedGroup = object;
|
needDeleted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deletedGroup) {
|
if (needDeleted) {
|
||||||
deletedGroups.push(deletedGroup);
|
deletedObject.push(currentObject);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,11 @@ class Range extends CtrlObject {
|
|||||||
*/
|
*/
|
||||||
public position: number[] = [];
|
public position: number[] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 半径
|
||||||
|
*/
|
||||||
|
public radius: number[] = [1, 1, 1];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Range;
|
export default Range;
|
||||||
|
@ -24,15 +24,23 @@ class Laboratory extends Component {
|
|||||||
const canvas = document.createElement("canvas");
|
const canvas = document.createElement("canvas");
|
||||||
const renderer = new ClassicRenderer(canvas, { className: "canvas" });
|
const renderer = new ClassicRenderer(canvas, { className: "canvas" });
|
||||||
this.canvasContRef.current.appendChild(renderer.canvas.dom);
|
this.canvasContRef.current.appendChild(renderer.canvas.dom);
|
||||||
|
|
||||||
renderer.onLoad();
|
renderer.onLoad();
|
||||||
|
|
||||||
let model = new Model();
|
let model = new Model().bindRenderer(renderer);
|
||||||
model.addGroup();
|
let group = model.addGroup();
|
||||||
model.addGroup();
|
let range = model.addRange();
|
||||||
|
range.color = [.1, .5, .9];
|
||||||
|
group.new(100);
|
||||||
|
group.color = [.8, .1, .6];
|
||||||
|
group.individuals.forEach((individual) => {
|
||||||
|
individual.position[0] = (Math.random() - .5) * 2;
|
||||||
|
individual.position[1] = (Math.random() - .5) * 2;
|
||||||
|
individual.position[2] = (Math.random() - .5) * 2;
|
||||||
|
})
|
||||||
|
model.update(0);
|
||||||
|
|
||||||
// 测试渲染器
|
// 测试渲染器
|
||||||
if (true) {
|
if (false) {
|
||||||
renderer.points("0");
|
renderer.points("0");
|
||||||
renderer.points("1", new Array(100 * 3).fill(0).map(() => (Math.random() - .5) * 2));
|
renderer.points("1", new Array(100 * 3).fill(0).map(() => (Math.random() - .5) * 2));
|
||||||
renderer.points("2", new Array(100 * 3).fill(0).map(() => (Math.random() - .5) * 2), {
|
renderer.points("2", new Array(100 * 3).fill(0).map(() => (Math.random() - .5) * 2), {
|
||||||
|
Loading…
Reference in New Issue
Block a user