Browse Source

application基本完成,数学库改写

master
blobt 3 years ago
parent
commit
a443b27abf
  1. 1
      src/render/common.ts
  2. 400
      src/render/core/Application.ts
  3. 88
      src/render/core/Event.ts
  4. 42
      src/render/core/Timer.ts
  5. 0
      src/render/ds/AdapterBase.ts
  6. 0
      src/render/ds/Dictionary.ts
  7. 0
      src/render/ds/IAdapter.ts
  8. 0
      src/render/ds/IEnumerator.ts
  9. 0
      src/render/ds/List.ts
  10. 0
      src/render/ds/ListNode.ts
  11. 0
      src/render/ds/NodeB2TEnumberator.ts
  12. 0
      src/render/ds/NodeEnumeratorFactory.ts
  13. 0
      src/render/ds/NodeT2BEnumerator.ts
  14. 0
      src/render/ds/Queue.ts
  15. 0
      src/render/ds/Stack.ts
  16. 0
      src/render/ds/TreeNode.ts
  17. 0
      src/render/ds/TypedArrayList.ts
  18. 0
      src/render/ds/index.ts
  19. 1537
      src/render/math/TSM.ts
  20. 42
      src/render/math/Vec2.ts
  21. 161
      src/render/math/Vec3.ts
  22. 10
      src/render/webgl/WebGLApplication.ts

1
src/render/common.ts

@ -0,0 +1 @@
export let EPSILON: number = 0.0001;

400
src/render/core/Application.ts

@ -0,0 +1,400 @@
import { vec2 } from "../math/TSM";
import { CanvasKeyBoardEvent, CanvasMouseEvent, EInputEventType } from "./Event";
import { Timer, TimerCallback } from "./Timer";
export class Application implements EventListenerObject {
/**
* @var
*/
public timers: Timer[] = [];
/**
* @var id
*/
private _timerId: number = -1;
/**
* @var
*/
private _fps: number = 0;
/**
* @var
*/
public isFlipYCoord: boolean = false;
/**
* @var
*/
public canvas: HTMLCanvasElement;
/**
* @var mouse事件
*/
public isSupportMouseMove: boolean;
/**
* @var
*/
protected _isMouseDown: boolean;
/**
* @var
*/
protected _isRightMouseDown: boolean = false;
/**
* @var
*/
protected _start: boolean = false;
/**
* @var Window对象的requestAnimationFrame返回的大于0的id号,
* 使cancelAnimationFrame ( this ._requestId ).
*/
protected _requestId: number = -1;
/**
* @var
*/
protected _lastTime !: number;
protected _startTime !: number;
/**
* @function
*/
public frameCallback: ((app: Application) => void) | null;
public constructor(canvas: HTMLCanvasElement) {
this.canvas = canvas;
//设置鼠标的监听事件
this.canvas.addEventListener("mousedown", this, false);
this.canvas.addEventListener("mouseup", this, false);
this.canvas.addEventListener("mousemove", this, false);
//设置键盘监听事件
window.addEventListener("keydown", this, false);
window.addEventListener("keyup", this, false);
window.addEventListener("keypress", this, false);
//初始化时候mousedown 和 mousemvoe不开启
this._isMouseDown = false;
this.isSupportMouseMove = false;
this.frameCallback = null;
//禁止右键菜单
document.oncontextmenu = function () { return false };
}
/**
* Application是否一直在调用requestAnimationFrame
* @returns boolean
*/
public isRunning(): boolean {
return this._start;
}
/**
*
*/
public get fps() {
return this._fps;
}
/**
*
*/
public start(): void {
if (this._start === false) {
this._start = true;
this._startTime = -1;
this._lastTime = -1;
this._requestId = requestAnimationFrame((msec: number): void => {
this.step(msec);
});
}
}
/**
*
* @param timeStamp
*/
protected step(timeStamp: number): void {
if (this._startTime === -1) {
this._startTime = timeStamp;
}
if (this._lastTime === -1) {
this._lastTime = timeStamp;
}
//计算当前时间和第一次调用step时候的时间差
let elapsedMsec = timeStamp - this._startTime;
//计算当前时间和上一次调用step时候的时间差
let intervalSec = timeStamp - this._lastTime;
this._lastTime = timeStamp;
//计算帧率
if (intervalSec !== 0) {
this._fps = 1000 / intervalSec;
}
intervalSec /= 1000.0; //转成秒
//处理timer
this._handleTimers(intervalSec);
//更新
this.update(elapsedMsec, intervalSec);
//渲染
this.render();
if (this.frameCallback !== null) {
this.frameCallback(this);
}
requestAnimationFrame((elapsedMsec: number): void => {
this.step(elapsedMsec);
})
}
public stop(): void {
if (this._start) {
cancelAnimationFrame(this._requestId);
this._startTime = -1;
this._lastTime = -1;
this._start = false;
}
}
/**
*
* @param elapsedMsec
* @param intervalSec
*/
public update(elapsedMsec: number, intervalSec: number): void { }
/**
*
*/
public render(): void { }
public async run(): Promise<void> {
this.start();
}
handleEvent(evt: Event): void {
switch (evt.type) {
case "mousedown":
this._isMouseDown = true;
this.onMouseDown(this._toCanvasMouseEvent(evt, EInputEventType.MOUSEDOWN));
break;
case "mouseup":
this._isMouseDown = false;
this.onMouseDown(this._toCanvasMouseEvent(evt, EInputEventType.MOUSEUP));
break;
case "mousemove":
if (this.isSupportMouseMove) {
this.onMouseMove(this._toCanvasMouseEvent(evt, EInputEventType.MOUSEMOVE));
}
if (this._isMouseDown) {
this.onMouseDrag(this._toCanvasMouseEvent(evt, EInputEventType.MOUSEDRAG));
}
break;
case "keypress":
this.onKeyPress(this._toCanvasKeyBoardEvent(evt, EInputEventType.KEYPRESS));
break;
case "keydown":
this.onKeyDown(this._toCanvasKeyBoardEvent(evt, EInputEventType.MOUSEDOWN));
break;
case "keyup":
this.onKeyUp(this._toCanvasKeyBoardEvent(evt, EInputEventType.KEYUP));
break;
}
}
protected onMouseDown(evt: CanvasMouseEvent): void {
return;
}
protected onMouseUp(evt: CanvasMouseEvent): void {
return;
}
protected onMouseMove(evt: CanvasMouseEvent): void {
return;
}
protected onMouseDrag(evt: CanvasMouseEvent): void {
return;
}
protected onKeyDown(evt: CanvasKeyBoardEvent): void {
return;
}
protected onKeyUp(evt: CanvasKeyBoardEvent): void {
return;
}
protected onKeyPress(evt: CanvasKeyBoardEvent): void {
return;
}
protected getMouseCanvas(): HTMLCanvasElement {
return this.canvas;
}
/**
* canvas的位置
* @param evt
*/
private viewportToCanvasCoordinate(evt: MouseEvent): vec2 {
let rect: ClientRect = this.getMouseCanvas().getBoundingClientRect();
//target是触发事件的元素,这里是canvas
if (evt.target) {
let x: number = evt.clientX - rect.left;
let y: number = evt.clientY - rect.top;
if (this.isFlipYCoord) {
y = this.getMouseCanvas().height - y;
}
let pos: vec2 = new vec2([x, y]);
return pos;
}
throw new Error("evt.target is null");
}
/**
* DOM
* @param evt
* @param type
*/
private _toCanvasMouseEvent(evt: Event, type: EInputEventType): CanvasMouseEvent {
let event: MouseEvent = evt as MouseEvent;//向下转型,将Event转换为MouseEvent
if (type === EInputEventType.MOUSEDOWN && event.button === 2) {
this._isRightMouseDown = true;
} else if (type === EInputEventType.MOUSEUP && event.button === 2) {
this._isRightMouseDown = false;
}
let buttonNum: number = event.button;
if (this._isRightMouseDown && type === EInputEventType.MOUSEDRAG) {
buttonNum = 2;
}
//将鼠标位置变换到canvas坐标系位置
let mousePosition: vec2 = this.viewportToCanvasCoordinate(event);
let ret: CanvasMouseEvent = new CanvasMouseEvent(type, mousePosition, buttonNum, event.altKey, event.ctrlKey, event.shiftKey);
return ret;
}
/**
* DOM
* @param evt
* @param type
*/
private _toCanvasKeyBoardEvent(evt: Event, type: EInputEventType): CanvasKeyBoardEvent {
let event: KeyboardEvent = evt as KeyboardEvent;
let ret: CanvasKeyBoardEvent = new CanvasKeyBoardEvent(type, event.key, event.keyCode, event.repeat, event.altKey, event.ctrlKey, event.shiftKey);
return ret;
}
/**
*
* @param callback
* @param timeout
* @param onlyOnce
* @param data
* @returns
*/
public addTimer(callback: TimerCallback, timeout: number = 1.0, onlyOnce: boolean = false, data: any = undefined): number {
let timer: Timer;
for (let i = 0; i < this.timers.length; i++) {
timer = this.timers[i];
if (timer.enabled === false) {
timer.callback = callback;
timer.callbackData = data;
timer.timeout = timeout;
timer.enabled = true;
timer.onlyOnce = onlyOnce;
return timer.id;
}
}
timer = new Timer(callback);
timer.callback = callback;
timer.callbackData = data;
timer.timeout = timeout;
timer.enabled = true;
timer.onlyOnce = onlyOnce;
this.timers.push(timer);
timer.id = ++this._timerId;
return timer.id;
}
/**
*
* @param id
* @returns
*/
public removeTimer(id: number): boolean {
let ret: boolean = false;
for (let i = 0; i < this.timers.length; i++) {
if (this.timers[i].id === id) {
let timer: Timer = this.timers[i];
timer.enabled = false;
ret = true;
break;
}
}
return ret;
}
/**
*
* @param intervalSec
*/
private _handleTimers(intervalSec: number): void {
for (let i = 0; i < this.timers.length; i++) {
let timer: Timer = this.timers[i];
if (timer.enabled === false) {
continue;
}
//countdown 初始化为timeout, 每次减少渲染时间
timer.countdown -= intervalSec;
if (timer.countdown <= 0.0) {
timer.callback(timer.id, timer.callbackData);
if (timer.onlyOnce) {
this.removeTimer(timer.id);
} else {
timer.callbackData = timer.timeout;
}
}
}
}
}

88
src/render/core/Event.ts

@ -0,0 +1,88 @@
import { vec2 } from "../math/TSM";
/**
* appliaction所有事件
*/
export enum EInputEventType {
MOUSEEVENT, //总类。表示鼠标事件
MOUSEDOWN,
MOUSEUP,
MOUSEMOVE,
MOUSEDRAG,
KEYBOARDEVENT, //总类,表示键盘事件
KEYUP,
KEYDOWN,
KEYPRESS
}
export class CanvasInputEvent {
/**
* @var alt键是否被按下
*/
public altKey: boolean;
/**
* @var ctrl键是否被按下
*/
public ctrlKey: boolean;
/**
* @var shift键是否被按下
*/
public shiftKey: boolean;
/**
* @var
*/
public type: EInputEventType;
public constructor(type: EInputEventType, altKey: boolean = false, ctrlKey: boolean = false, shiftKey: boolean = false) {
this.type = type;
this.altKey = altKey;
this.ctrlKey = ctrlKey;
this.shiftKey = shiftKey;
}
}
export class CanvasMouseEvent extends CanvasInputEvent {
/**
* @var 0 : 鼠标左键 1 2
*/
public button: number;
/**
* @var canvas
*/
public canvasPosition: vec2;
public constructor(type: EInputEventType, canvasPos: vec2, button: number, altKey: boolean = false, ctrlKey: boolean = false, shiftKey:boolean = false){
super(type,altKey, ctrlKey, shiftKey);
this.canvasPosition = canvasPos;
this.button = button;
}
}
export class CanvasKeyBoardEvent extends CanvasInputEvent {
/**
* @var
*/
public key:string;
/**
* @var ascii码
*/
public keyCode:number;
/**
* @var
*/
public repeat:boolean;
public constructor(type: EInputEventType, key:string, keyCode:number, repeat: boolean, altKey: boolean = false, ctrlKey: boolean = false, shiftKey:boolean = false){
super(type,altKey, ctrlKey, shiftKey);
this.key = key;
this.keyCode = keyCode;
this.repeat = repeat;
}
}

42
src/render/core/Timer.ts

@ -0,0 +1,42 @@
export type TimerCallback = (id: number, data: any) => void;
export class Timer {
/**
* @var id
*/
public id: number = -1;
/**
* @var
*/
public enabled: boolean = false;
/**
* @function
*/
public callback: TimerCallback;
/**
* @var
*/
public callbackData: any = undefined;
/**
* @var update次数
*/
public countdown: number = 0;
/**
* @var
*/
public timeout: number = 0;
/**
* @var
*/
public onlyOnce: boolean = false;
constructor(callback: TimerCallback){
this.callback = callback;
}
}

src/render/AdapterBase.ts → src/render/ds/AdapterBase.ts

src/render/Dictionary.ts → src/render/ds/Dictionary.ts

src/render/IAdapter.ts → src/render/ds/IAdapter.ts

src/render/IEnumerator.ts → src/render/ds/IEnumerator.ts

src/render/List.ts → src/render/ds/List.ts

src/render/ListNode.ts → src/render/ds/ListNode.ts

src/render/NodeB2TEnumberator.ts → src/render/ds/NodeB2TEnumberator.ts

src/render/NodeEnumeratorFactory.ts → src/render/ds/NodeEnumeratorFactory.ts

src/render/NodeT2BEnumerator.ts → src/render/ds/NodeT2BEnumerator.ts

src/render/Queue.ts → src/render/ds/Queue.ts

src/render/Stack.ts → src/render/ds/Stack.ts

src/render/TreeNode.ts → src/render/ds/TreeNode.ts

src/render/TypedArrayList.ts → src/render/ds/TypedArrayList.ts

src/render/index.ts → src/render/ds/index.ts

1537
src/render/math/TSM.ts
File diff suppressed because it is too large
View File

42
src/render/math/Vec2.ts

@ -0,0 +1,42 @@
/**
*
*/
export class Vec2 {
/**
* @var
*/
public values = new Float32Array(2);
public get x(): number {
return this.values[0];
}
public get y(): number {
return this.values[1];
}
public set x(value: number) {
this.values[0] = value;
}
public set y(value: number) {
this.values[1] = value;
}
public constructor(values: number[] | null = null) {
if (values) {
this.x = values[0];
this.y = values[1];
} else {
this.x = this.y = 0;
}
}
copy(dest: Vec2 | null = null): Vec2 {
if (!dest) dest = new Vec2();
dest.x = this.x;
dest.y = this.y;
return dest;
}
}

161
src/render/math/Vec3.ts

@ -0,0 +1,161 @@
import { EPSILON } from "../common";
export class Vec3 {
/**
* @var
*/
public values = new Float32Array(3);
public get x(): number {
return this.values[0];
}
public get y(): number {
return this.values[1];
}
public get z(): number {
return this.values[2];
}
public set x(value: number) {
this.values[0] = value;
}
public set y(value: number) {
this.values[1] = value;
}
public set z(value: number) {
this.values[2] = value;
}
public constructor(values: number[] | null = null) {
if (values !== null) {
this.x = values[0];
this.y = values[1];
this.z = values[2];
} else {
this.x = this.y = this.z = 0;
}
}
public at(index: number): number {
return this.values[index];
}
public reset(x: number = 0, y: number = 0, z: number = 0): void {
this.x = x;
this.y = y;
this.z = z;
}
public copy(dest: Vec3 | null = null): Vec3 {
if (!dest) dest = new Vec3();
dest.x = this.x;
dest.y = this.y;
dest.z = this.z;
return dest;
}
/**
*
* @param dest
* @returns
*/
public negate(dest: Vec3 | null = null): Vec3 {
if (!dest) dest = this;
dest.x = -this.x;
dest.y = -this.y;
dest.z = -this.z;
return dest;
}
/**
*
* @param vector
* @param threshold
* @returns
*/
public equals(vector: Vec3, threshold = EPSILON): boolean {
if (Math.abs(this.x - vector.x) > threshold)
return false;
if (Math.abs(this.y - vector.y) > threshold)
return false;
if (Math.abs(this.z - vector.z) > threshold)
return false;
return true;
}
/**
*
*/
public get length(): number {
return Math.sqrt(this.length2);
}
/**
*
*/
public get length2(): number {
let x = this.x,
y = this.y,
z = this.z;
return (x * x + y * y + z * z);
}
/**
*
* @param vector
* @returns
*/
add(vector: Vec3): Vec3 {
this.x += vector.x;
this.y += vector.y;
this.z += vector.z;
return this;
}
/**
*
* @param vector
* @returns
*/
subtract(vector: Vec3): Vec3 {
this.x -= vector.x;
this.y -= vector.y;
this.z -= vector.z;
return this;
}
/**
*
* @param value
* @param dest
* @returns
*/
public scale(value: number, dest: Vec3 | null = null): Vec3 {
if (!dest) {
dest = this;
} else {
this.copy(dest);
}
dest.x *= value;
dest.y *= value;
dest.z *= value;
return dest;
}
}

10
src/render/webgl/WebGLApplication.ts

@ -0,0 +1,10 @@
import { Application } from "../core/Application";
export class WebGLApplication extends Application {
/**
* @var WebGL
*/
//public gl: WebGLRenderingContext;
}
Loading…
Cancel
Save